Re: [PATCH V8 03/43] drm/doc/rfc: Describe why prescriptive color pipeline is needed

2025-03-31 Thread Alex Hung




On 3/29/25 09:26, Simon Ser wrote:

I would also highlight that we need to seamlessly switch between HW
fixed-function blocks and shaders/CPU with no visible difference. Depending on
the content being displayed we might need to fallback to shaders/CPU at any
time. (A classic example would be a new notification popup preventing us from
leveraging KMS planes.)


Yes that would be the goal.

Is there any part of the docs that still need revising to clarify this?


Re: [PATCH v2 1/2] drm/msm/dp: Fix support of LTTPR handling

2025-03-31 Thread Dmitry Baryshkov
On Wed, Mar 12, 2025 at 12:38:03AM +0100, Aleksandrs Vinarskis wrote:
> Take into account LTTPR capabilities when selecting maximum allowed
> link rate, number of data lines. Initialize LTTPR before
> msm_dp_panel_read_sink_caps, as
> a) Link params computation need to take into account LTTPR's caps
> b) It appears DPTX shall (re)read DPRX caps after LTTPR detection

... as required by DP 2.1, Section 3.6.7.6.1

Split this into two patches.

> 
> Return lttpr_count to prepare for per-segment link training.

And this one is the third one.

> 
> Signed-off-by: Aleksandrs Vinarskis 
> Reviewed-by: Abel Vesa 
> ---
>  drivers/gpu/drm/msm/dp/dp_display.c | 29 +++-
>  drivers/gpu/drm/msm/dp/dp_panel.c   | 30 -
>  drivers/gpu/drm/msm/dp/dp_panel.h   |  2 ++
>  3 files changed, 43 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index bbc47d86ae9e..d0c2dc7e6648 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -108,6 +108,8 @@ struct msm_dp_display_private {
>   struct msm_dp_event event_list[DP_EVENT_Q_MAX];
>   spinlock_t event_lock;
>  
> + u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];

It would feel more natural to have lttpr_common_caps inside msm_dp_panel
rather than here.

> +
>   bool wide_bus_supported;
>  
>   struct msm_dp_audio *audio;
> @@ -367,17 +369,21 @@ static int msm_dp_display_send_hpd_notification(struct 
> msm_dp_display_private *d
>   return 0;
>  }
>  
> -static void msm_dp_display_lttpr_init(struct msm_dp_display_private *dp)
> +static int msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 
> *dpcd)

Hmm, why? Return code is still unused in this patch. If it is a
preparation for the next one, it should be split into a separate patch.

>  {
> - u8 lttpr_caps[DP_LTTPR_COMMON_CAP_SIZE];
> - int rc;
> + int rc, lttpr_count;
>  
> - if (drm_dp_read_lttpr_common_caps(dp->aux, dp->panel->dpcd, lttpr_caps))
> - return;
> + if (drm_dp_read_lttpr_common_caps(dp->aux, dpcd, dp->lttpr_common_caps))
> + return 0;
>  
> - rc = drm_dp_lttpr_init(dp->aux, drm_dp_lttpr_count(lttpr_caps));
> - if (rc)
> + lttpr_count = drm_dp_lttpr_count(dp->lttpr_common_caps);
> + rc = drm_dp_lttpr_init(dp->aux, lttpr_count);
> + if (rc) {
>   DRM_ERROR("failed to set LTTPRs transparency mode, rc=%d\n", 
> rc);
> + return 0;
> + }
> +
> + return lttpr_count;
>  }
>  
>  static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)

[...]

> @@ -64,16 +67,24 @@ static int msm_dp_panel_read_dpcd(struct msm_dp_panel 
> *msm_dp_panel)
>   major = (link_info->revision >> 4) & 0x0f;
>   minor = link_info->revision & 0x0f;
>  
> - link_info->rate = drm_dp_max_link_rate(dpcd);
> - link_info->num_lanes = drm_dp_max_lane_count(dpcd);
> + max_source_lanes = msm_dp_panel->max_dp_lanes;
> + max_source_rate = msm_dp_panel->max_dp_link_rate;
>  
> - /* Limit data lanes from data-lanes of endpoint property of dtsi */
> - if (link_info->num_lanes > msm_dp_panel->max_dp_lanes)
> - link_info->num_lanes = msm_dp_panel->max_dp_lanes;
> + max_sink_lanes = drm_dp_max_lane_count(dpcd);
> + max_sink_rate = drm_dp_max_link_rate(dpcd);
> +
> + max_lttpr_lanes = drm_dp_lttpr_max_lane_count(lttpr_common_caps);
> + max_lttpr_rate = drm_dp_lttpr_max_link_rate(lttpr_common_caps);
>  
> + if (max_lttpr_lanes)
> + max_sink_lanes = min(max_sink_lanes, max_lttpr_lanes);
> + if (max_lttpr_rate)
> + max_sink_rate = min(max_sink_rate, max_lttpr_rate);
> +
> + /* Limit data lanes from data-lanes of endpoint property of dtsi */
> + link_info->num_lanes = min(max_sink_lanes, max_source_lanes);
>   /* Limit link rate from link-frequencies of endpoint property of dtsi */
> - if (link_info->rate > msm_dp_panel->max_dp_link_rate)
> - link_info->rate = msm_dp_panel->max_dp_link_rate;
> + link_info->rate = min(max_sink_rate, max_source_rate);


Please keep existing code and extend it to handle max_lttpr_lanes /
max_lttpr_rate instead of rewriting it unnecessarily.

>  
>   drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);
>   drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);

-- 
With best wishes
Dmitry


Re: [PATCH V8 24/43] drm/amd/display: Skip color pipeline initialization for cursor plane

2025-03-31 Thread Alex Hung




On 3/31/25 19:04, Shengyu Qu wrote:


My understanding is that currently the driver would just report no 
colorop support on cursor plane and actually implement the background 
plane's colorop on cursor?


No.





Again it is up to compositors or apps to determine how color pipeline 
and colorops are used (or not). For example, both primary plane and 
overlay plane have the same color pipeline, HDR can be enabled only on 
overlay but not on primary.
Still this is the cleanest way to let compositors know and deal with 
this special cursor plane behavior. Or if compositors want to use all 
planes with hw colorop + MPO(for power saving or sth.), they have to 
detect the gpu they are running on and apply a quirk for this. That's a 
"dirty" implementation.


Unrelated to color pipeline.


Re: [PATCH V8 43/43] drm/colorop: Add destroy functions for color pipeline

2025-03-31 Thread Alex Hung




On 3/29/25 09:48, Simon Ser wrote:

I would prefer these functions to be introduced together with the
patches adding functions to create objects and adding the new fields.
That way it's easier to check the symmetry and at no point in the
series there are memory leaks.


The object creation and new fields are introduced in different patches. 
I divided this patch by introducing these functions in a patch, and 2. 
adding callers when needed to avoid memory leaks.




Additionally, I would avoid using the name "cleanup", which seems to
have different semantics: for instance drm_plane_cleanup() doesn't kfree
the pointer. "destroy" seems more appropriate here.


How about the following changes, i.e., freeing pointer is moved out of 
the cleanup function, and keeping the names.


@@ -173,7 +173,6 @@ static void drm_colorop_cleanup(struct drm_colorop 
*colorop)

}

kfree(colorop->state);
-   kfree(colorop);
 }

 /**
@@ -191,6 +190,7 @@ void drm_colorop_pipeline_destroy(struct drm_plane 
*plane)


list_for_each_entry_safe(colorop, next, &config->colorop_list, 
head) {

drm_colorop_cleanup(colorop);
+   kfree(colorop);
}
 }




[PATCH v3] backlight: pm8941: Add NULL check in wled_configure()

2025-03-31 Thread Henry Martin
Thanks for your review. No further improvements needed for this implementation
- it already handles all error cases appropriately.

Best regards,
Henry


Re: [PATCH v2] backlight: pm8941: Add NULL check in wled_configure()

2025-03-31 Thread Markus Elfring
> devm_kasprintf() return NULL if memory allocation fails. Currently,

 call?   failed?


> wled_configure() does not check for this case, leading to a possible NULL
> pointer dereference.

You may omit the word “possible” in such a change description.
(Would questionable data processing happen in other function implementations?)


> Add NULL check after devm_kasprintf() to prevent this issue.

Do you complete the error/exception handling also with the statement “return 
-ENOMEM;”?

Regards,
Markus


Re: [PATCH v1 2/3] drm/ci: Add jobs to validate devicetrees

2025-03-31 Thread Vignesh Raman

Hi Dmitry,

On 30/03/25 22:36, Dmitry Baryshkov wrote:

On Thu, Mar 27, 2025 at 09:31:11PM +0530, Vignesh Raman wrote:

Add jobs to run dt_binding_check and dtbs_check. If warnings are seen,
exit with a non-zero error code while configuring them as warning in
the GitLab CI pipeline.


Can it really succeed or is it going to be an always-failing job? The
dt_binding_check generally succeed, dtbs_check generates tons of
warnings. We are trying to make progress there, but it's still very far
from being achevable.


Even though it fails, it will be shown as a warning in the pipeline.
https://gitlab.freedesktop.org/vigneshraman/linux/-/pipelines/1390797





Signed-off-by: Vignesh Raman 
---
  drivers/gpu/drm/ci/check-devicetrees.yml | 38 ++
  drivers/gpu/drm/ci/dt-binding-check.sh   | 18 +++
  drivers/gpu/drm/ci/dtbs-check.sh | 41 
  drivers/gpu/drm/ci/gitlab-ci.yml |  1 +
  4 files changed, 98 insertions(+)
  create mode 100644 drivers/gpu/drm/ci/check-devicetrees.yml
  create mode 100755 drivers/gpu/drm/ci/dt-binding-check.sh
  create mode 100755 drivers/gpu/drm/ci/dtbs-check.sh

diff --git a/drivers/gpu/drm/ci/check-devicetrees.yml 
b/drivers/gpu/drm/ci/check-devicetrees.yml
new file mode 100644
index ..5f0c477f7578
--- /dev/null
+++ b/drivers/gpu/drm/ci/check-devicetrees.yml
@@ -0,0 +1,38 @@
+.dt-check-base:
+  timeout: "1h"
+  variables:
+FF_USE_NEW_BASH_EVAL_STRATEGY: 'true'
+  script:
+- drivers/gpu/drm/ci/${SCRIPT_NAME}
+  artifacts:
+when: on_failure
+paths:
+  - ${ARTIFACT_FILE}
+  allow_failure:
+exit_codes:
+  - 102
+
+dtbs-check:arm32:
+  extends:
+- .build:arm32
+- .dt-check-base
+  variables:
+SCRIPT_NAME: "dtbs-check.sh"
+ARTIFACT_FILE: "dtbs-check.log"
+
+dtbs-check:arm64:
+  extends:
+- .build:arm64
+- .dt-check-base
+  variables:
+SCRIPT_NAME: "dtbs-check.sh"
+ARTIFACT_FILE: "dtbs-check.log"
+
+dt-binding-check:
+  extends:
+- .build
+- .use-debian/x86_64_build
+- .dt-check-base
+  variables:
+SCRIPT_NAME: "dt-binding-check.sh"
+ARTIFACT_FILE: "dt-binding-check.log"
diff --git a/drivers/gpu/drm/ci/dt-binding-check.sh 
b/drivers/gpu/drm/ci/dt-binding-check.sh
new file mode 100755
index ..2a72bb89c013
--- /dev/null
+++ b/drivers/gpu/drm/ci/dt-binding-check.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# SPDX-License-Identifier: MIT
+
+set -euxo pipefail
+
+apt-get update -qq
+apt install -y --no-install-recommends yamllint
+pip3 install dtschema
+
+if ! make -j${FDO_CI_CONCURRENT:-4} dt_binding_check >/dev/null 
2>dt-binding-check.log; then


I'd rather see errors in job output too.


Will update it.




+echo "ERROR: 'make dt_binding_check' failed. Please check dt-binding-check.log 
for details."
+exit 1
+fi
+
+if [[ -s dt-binding-check.log ]]; then
+echo "WARNING: dt_binding_check reported warnings. Please check 
dt-binding-check.log for details."
+exit 102
+fi
diff --git a/drivers/gpu/drm/ci/dtbs-check.sh b/drivers/gpu/drm/ci/dtbs-check.sh
new file mode 100755
index ..a0129d5a53b0
--- /dev/null
+++ b/drivers/gpu/drm/ci/dtbs-check.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# SPDX-License-Identifier: MIT
+
+set -euxo pipefail
+
+. drivers/gpu/drm/ci/override-ld-with-bfd.sh
+
+apt-get update -qq
+pip3 install dtschema
+
+case "${KERNEL_ARCH}" in
+"arm")
+GCC_ARCH="arm-linux-gnueabihf"
+;;
+"arm64")
+GCC_ARCH="aarch64-linux-gnu"
+;;
+"x86_64")
+GCC_ARCH="x86_64-linux-gnu"
+;;
+*)
+echo "Unsupported architecture: ${KERNEL_ARCH}"
+exit 1
+;;
+esac
+
+export ARCH="${KERNEL_ARCH}"
+export CROSS_COMPILE="${GCC_ARCH}-"
+
+make `basename ${DEFCONFIG}`
+make -j${FDO_CI_CONCURRENT:-4} dtbs


You don't need to build dtbs separately, dtbs_check includes dtbs.


Ack. Will remove this.




+
+if ! make -j${FDO_CI_CONCURRENT:-4} dtbs_check >/dev/null 2>dtbs-check.log; 
then


I'd rather see errors in job output too.


Will update it.

Regards,
Vignesh




+echo "ERROR: 'make dtbs_check' failed. Please check dtbs-check.log for 
details."
+exit 1
+fi
+
+if [[ -s dtbs-check.log ]]; then
+echo "WARNING: dtbs_check reported warnings. Please check dtbs-check.log for 
details."
+exit 102
+fi
diff --git a/drivers/gpu/drm/ci/gitlab-ci.yml b/drivers/gpu/drm/ci/gitlab-ci.yml
index 65adcd97e06b..9e61b49e9960 100644
--- a/drivers/gpu/drm/ci/gitlab-ci.yml
+++ b/drivers/gpu/drm/ci/gitlab-ci.yml
@@ -108,6 +108,7 @@ include:
- drivers/gpu/drm/ci/static-checks.yml
- drivers/gpu/drm/ci/build.yml
- drivers/gpu/drm/ci/test.yml
+  - drivers/gpu/drm/ci/check-devicetrees.yml
- 
'https://gitlab.freedesktop.org/gfx-ci/lab-status/-/raw/main/lab-status.yml'
  
  
--

2.47.2







Re: [PATCH v2] drm/panel: boe-bf060y8m-aj0: transition to mipi_dsi wrapped functions

2025-03-31 Thread Dmitry Baryshkov
On Tue, Apr 01, 2025 at 04:01:03AM +0300, Dmitry Baryshkov wrote:
> On Mon, Mar 31, 2025 at 03:40:27PM -0700, Doug Anderson wrote:
> > Hi,
> > 
> > On Mon, Mar 31, 2025 at 1:28 PM Dmitry Baryshkov
> >  wrote:
> > >
> > > On Mon, Mar 31, 2025 at 08:06:36AM -0700, Doug Anderson wrote:
> > > > Hi,
> > > >
> > > > On Sun, Mar 30, 2025 at 11:18 PM Tejas Vipin  
> > > > wrote:
> > > > >
> > > > > @@ -157,7 +137,6 @@ static int boe_bf060y8m_aj0_prepare(struct 
> > > > > drm_panel *panel)
> > > > >
> > > > > ret = boe_bf060y8m_aj0_on(boe);
> > > > > if (ret < 0) {
> > > > > -   dev_err(dev, "Failed to initialize panel: %d\n", ret);
> > > > > gpiod_set_value_cansleep(boe->reset_gpio, 1);
> > > > > return ret;
> > > >
> > > > It's not new, but the error handling here looks wrong to me. Instead
> > > > of just returning after setting the GPIO, this should be turning off
> > > > the regulators, shouldn't it? That would mean adding a new error label
> > > > for turning off "BF060Y8M_VREG_VCI" and then jumping to that.
> > >
> > > We should not be turning off the regulator in _prepare(), there will be
> > > an unmatched regulator disable call happening in _unprepare(). Of course
> > > it can be handled by adding a boolean, etc, but I think keeping them on
> > > is a saner thing.
> > 
> > Hr.
> > 
> > The issue is that if we're returning an error from a function the
> > caller should expect that the function undid anything that it did
> > partially. It _has_ to work that way, right? Otherwise we've lost the
> > context of exactly how far we got through the function so we don't
> > know which things to later undo and which things to later not undo.
> 
> Kind of yes. I'd rather make drm_panel functions return void here, as
> that matches panel bridge behaviour. The only driver that actually uses
> return values of those functions is analogix_dp, see
> analogix_dp_prepare_panel(). However most of invocations of that
> function can go away. I'll send a patchset.
> 
> > 
> > ...although I think you said that the DRM framework ignores errors
> > from prepare() and still calls unprepare(). I guess this is in
> > panel_bridge_atomic_pre_enable() where drm_panel_prepare()'s error
> > code is ignored?
> 

Hmm... Most of the drivers ignore the results of the drm_panel_prepare()
/ _unprepare() / _enable() / _disable(), but then the framework handles
error values of the callbacks and skips calling the corresponding
en/dis callback if the previous call has failed. Which means I was
incorrect here.

> 
> > This feels like a bug waiting to happen. Are you
> > saying that boe_bf060y8m_aj0_unprepare() has to be written such that
> > it doesn't hit regulator underflows no matter which fail path
> > boe_bf060y8m_aj0_prepare() hit? That feels wrong.
> 
> Let me try to fix that.
> 
> -- 
> With best wishes
> Dmitry

-- 
With best wishes
Dmitry


[PATCH] backlight: qcom-wled: Add NULL check in the wled_configure

2025-03-31 Thread Henry Martin
When devm_kasprintf() fails, it returns a NULL pointer. However, this return 
value is not properly checked in the function wled_configure.

A NULL check should be added after the devm_kasprintf call to prevent potential 
NULL pointer dereference error.

Fixes: f86b77583d88c ("backlight: pm8941: Convert to using %pOFn instead of 
device_node.name")

Signed-off-by: Henry Martin 
---
 drivers/video/backlight/qcom-wled.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 9afe701b2a1b..db5eda8ec37e 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -1406,8 +1406,14 @@ static int wled_configure(struct wled *wled)
wled->ctrl_addr = be32_to_cpu(*prop_addr);
 
rc = of_property_read_string(dev->of_node, "label", &wled->name);
-   if (rc)
+   if (rc) {
wled->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn", 
dev->of_node);
+   if (!wled->name) {
+   dev_err(dev, "Failed to allocate memory for wled 
name\n");
+   return -ENOMEM;
+   }
+   }
+
 
switch (wled->version) {
case 3:
-- 
2.34.1



Re: [PATCH 12/12] drm/i915/display: Expose sharpness strength property

2025-03-31 Thread Nautiyal, Ankit K



On 3/21/2025 9:36 PM, Nemesa Garg wrote:

Expose the drm crtc sharpness strength property which will enable
or disable the sharpness/casf based on user input. With this user
can set/update the strength of the sharpness or casf filter.

v2: Update subject[Ankit]

Signed-off-by: Nemesa Garg 


Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/i915/display/intel_crtc.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c 
b/drivers/gpu/drm/i915/display/intel_crtc.c
index 5b2603ef2ff7..b8bd255e9555 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -391,6 +391,9 @@ int intel_crtc_init(struct intel_display *display, enum 
pipe pipe)
  
  	drm_WARN_ON(display->drm, drm_crtc_index(&crtc->base) != crtc->pipe);
  
+	if (HAS_CASF(dev_priv))

+   drm_crtc_create_sharpness_strength_property(&crtc->base);
+
return 0;
  
  fail:


[PATCH v2 16/18] drm/sysfb: Add vesadrm for VESA displays

2025-03-31 Thread Thomas Zimmermann
Add support for screen_info setups with VIDEO_TYPE_VLFB. Provide the
minimum functionality of reading modes, updating and clearing the display.

There is existing support for these displays provided by simpledrm with
CONFIG_SYSFB_SIMPLEFB=y. Using vesadrm over simpledrm will allow for the
use of additional functionality provided by VESA, such as EDID information,
gamma correction and palette modes. This enhances the user experience and
adds support for more display configuratons.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/sysfb/Kconfig   |  16 ++
 drivers/gpu/drm/sysfb/Makefile  |   1 +
 drivers/gpu/drm/sysfb/vesadrm.c | 448 
 3 files changed, 465 insertions(+)
 create mode 100644 drivers/gpu/drm/sysfb/vesadrm.c

diff --git a/drivers/gpu/drm/sysfb/Kconfig b/drivers/gpu/drm/sysfb/Kconfig
index 3ffd8da1224cf..008c33eab99a4 100644
--- a/drivers/gpu/drm/sysfb/Kconfig
+++ b/drivers/gpu/drm/sysfb/Kconfig
@@ -57,4 +57,20 @@ config DRM_SIMPLEDRM
  On x86 BIOS or UEFI systems, you should also select SYSFB_SIMPLEFB
  to use UEFI and VESA framebuffers.
 
+config DRM_VESADRM
+   tristate "VESA framebuffer driver"
+   depends on DRM && MMU
+   select APERTURE_HELPERS
+   select DRM_CLIENT_SELECTION
+   select DRM_GEM_SHMEM_HELPER
+   select DRM_KMS_HELPER
+   select DRM_SYSFB_HELPER
+   select SYSFB
+   help
+ DRM driver for VESA framebuffers.
+
+ This driver assumes that the display hardware has been initialized
+ by the firmware or bootloader before the kernel boots. Scanout
+ buffer, size, and display format must be provided via VBE interfaces.
+
 endmenu
diff --git a/drivers/gpu/drm/sysfb/Makefile b/drivers/gpu/drm/sysfb/Makefile
index 2f96f52842e63..0d2518c971634 100644
--- a/drivers/gpu/drm/sysfb/Makefile
+++ b/drivers/gpu/drm/sysfb/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_SYSFB_HELPER)  += drm_sysfb_helper.o
 obj-$(CONFIG_DRM_EFIDRM)   += efidrm.o
 obj-$(CONFIG_DRM_OFDRM)+= ofdrm.o
 obj-$(CONFIG_DRM_SIMPLEDRM)+= simpledrm.o
+obj-$(CONFIG_DRM_VESADRM)  += vesadrm.o
diff --git a/drivers/gpu/drm/sysfb/vesadrm.c b/drivers/gpu/drm/sysfb/vesadrm.c
new file mode 100644
index 0..8a963057ffec9
--- /dev/null
+++ b/drivers/gpu/drm/sysfb/vesadrm.c
@@ -0,0 +1,448 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "drm_sysfb_helper.h"
+
+#define DRIVER_NAME"vesadrm"
+#define DRIVER_DESC"DRM driver for VESA platform devices"
+#define DRIVER_MAJOR   1
+#define DRIVER_MINOR   0
+
+static int vesadrm_get_validated_int(struct drm_device *dev, const char *name,
+u64 value, u32 max)
+{
+   if (max > INT_MAX)
+   max = INT_MAX;
+   if (value > max) {
+   drm_err(dev, "%s of %llu exceeds maximum of %u\n", name, value, 
max);
+   return -EINVAL;
+   }
+   return value;
+}
+
+static int vesadrm_get_validated_int0(struct drm_device *dev, const char *name,
+ u64 value, u32 max)
+{
+   if (!value) {
+   drm_err(dev, "%s of 0 not allowed\n", name);
+   return -EINVAL;
+   }
+   return vesadrm_get_validated_int(dev, name, value, max);
+}
+
+static s64 vesadrm_get_validated_size0(struct drm_device *dev, const char 
*name,
+  u64 value, u64 max)
+{
+   if (!value) {
+   drm_err(dev, "vesadrm: %s of 0 not allowed\n", name);
+   return -EINVAL;
+   } else if (value > max) {
+   drm_err(dev, "vesadrm: %s of %llu exceeds maximum of %llu\n", 
name, value, max);
+   return -EINVAL;
+   }
+   return value;
+}
+
+static int vesadrm_get_width_si(struct drm_device *dev, const struct 
screen_info *si)
+{
+   return vesadrm_get_validated_int0(dev, "width", si->lfb_width, U16_MAX);
+}
+
+static int vesadrm_get_height_si(struct drm_device *dev, const struct 
screen_info *si)
+{
+   return vesadrm_get_validated_int0(dev, "height", si->lfb_height, 
U16_MAX);
+}
+
+static struct resource *vesadrm_get_memory_si(struct drm_device *dev,
+ const struct screen_info *si,
+ struct resource *res)
+{
+   ssize_t num;
+
+   num = screen_info_resources(si, res, 1);
+   if (!num) {
+   drm_err(dev, "vesadrm: memory resource not found\n");
+   return NULL;
+   }
+
+   return res;
+}
+
+static int vesadrm_get_stride_si(struct drm_device *dev, const struct 
screen_info *si,
+const struct drm_format_i

Re: [PATCH 1/1] fbdev: atyfb: Fix buffer overflow

2025-03-31 Thread Ville Syrjälä
On Thu, Mar 27, 2025 at 12:14:26PM +0200, Jani Nikula wrote:
> On Thu, 27 Mar 2025, Denis Arefev  wrote:
> > The value LCD_MISC_CNTL is used in the 'aty_st_lcd()' function to
> > calculate an index for accessing an array element of size 9.
> > This may cause a buffer overflow.
> 
> The fix is to fix it, not silently brush it under the carpet.

There's actually nothing to fix. The backlight code is only
used on Rage Mobility which has real indexed LCD registers.

Older chips do supposedly have backlight control as well,
but implemented differently. I was mildly curious about
this stuff, so I I poked at my Rage LT Pro a bit to see
if I could get backlight control working on it, but the
only things I was able to achieve were either backlight
completely off, or blinking horribly. So looks like at least
on this machine (Dell Insipiron 7000) the backlight is
implemented in a way that can't be controller via the
normal registers. The machine does have brightness keys that
do work (though the difference between the min and max is
barely noticeable) but they don't result in any changes in
the relevant registers.

> 
> BR,
> Jani.
> 
> >
> > Found by Linux Verification Center (linuxtesting.org) with SVACE.
> >
> > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> > Signed-off-by: Denis Arefev 
> > ---
> >  drivers/video/fbdev/aty/atyfb_base.c | 4 
> >  1 file changed, 4 insertions(+)
> >
> > diff --git a/drivers/video/fbdev/aty/atyfb_base.c 
> > b/drivers/video/fbdev/aty/atyfb_base.c
> > index 210fd3ac18a4..93eb5eb6042b 100644
> > --- a/drivers/video/fbdev/aty/atyfb_base.c
> > +++ b/drivers/video/fbdev/aty/atyfb_base.c
> > @@ -149,6 +149,8 @@ static const u32 lt_lcd_regs[] = {
> >  void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
> >  {
> > if (M64_HAS(LT_LCD_REGS)) {
> > +   if ((u32)index >= ARRAY_SIZE(lt_lcd_regs))
> > +   return;
> > aty_st_le32(lt_lcd_regs[index], val, par);
> > } else {
> > unsigned long temp;
> > @@ -164,6 +166,8 @@ void aty_st_lcd(int index, u32 val, const struct 
> > atyfb_par *par)
> >  u32 aty_ld_lcd(int index, const struct atyfb_par *par)
> >  {
> > if (M64_HAS(LT_LCD_REGS)) {
> > +   if ((u32)index >= ARRAY_SIZE(lt_lcd_regs))
> > +   return 0;
> > return aty_ld_le32(lt_lcd_regs[index], par);
> > } else {
> > unsigned long temp;
> 
> -- 
> Jani Nikula, Intel

-- 
Ville Syrjälä
Intel


[PATCH 7/7] drm/panel: make prepare/enable and disable/unprepare calls return void

2025-03-31 Thread Dmitry Baryshkov
Now there are no users of the return value of the drm_panel_prepare(),
drm_panel_unprepare(), drm_panel_enable() and drm_panel_disable() calls.
Usually these calls are performed from the atomic callbacks, where it is
impossible to return an error. Stop returning error codes and return
void instead.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/drm_panel.c | 54 +
 drivers/gpu/drm/panel/panel-newvision-nv3051d.c |  9 +
 include/drm/drm_panel.h |  8 ++--
 3 files changed, 26 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index 
c627e42a7ce70459f50eb5095fffc806ca45dabf..faa7a76b63b53b3a45b3400d8bf3b58a027a340e
 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -105,21 +105,21 @@ EXPORT_SYMBOL(drm_panel_remove);
  *
  * Calling this function will enable power and deassert any reset signals to
  * the panel. After this has completed it is possible to communicate with any
- * integrated circuitry via a command bus.
- *
- * Return: 0 on success or a negative error code on failure.
+ * integrated circuitry via a command bus. This function cannot fail (as it is
+ * called from the pre_enable call chain). There will always be a call to
+ * drm_panel_disable() afterwards.
  */
-int drm_panel_prepare(struct drm_panel *panel)
+void drm_panel_prepare(struct drm_panel *panel)
 {
struct drm_panel_follower *follower;
int ret;
 
if (!panel)
-   return -EINVAL;
+   return;
 
if (panel->prepared) {
dev_warn(panel->dev, "Skipping prepare of already prepared 
panel\n");
-   return 0;
+   return;
}
 
mutex_lock(&panel->follower_lock);
@@ -138,11 +138,8 @@ int drm_panel_prepare(struct drm_panel *panel)
 follower->funcs->panel_prepared, ret);
}
 
-   ret = 0;
 exit:
mutex_unlock(&panel->follower_lock);
-
-   return ret;
 }
 EXPORT_SYMBOL(drm_panel_prepare);
 
@@ -154,16 +151,14 @@ EXPORT_SYMBOL(drm_panel_prepare);
  * reset, turn off power supplies, ...). After this function has completed, it
  * is usually no longer possible to communicate with the panel until another
  * call to drm_panel_prepare().
- *
- * Return: 0 on success or a negative error code on failure.
  */
-int drm_panel_unprepare(struct drm_panel *panel)
+void drm_panel_unprepare(struct drm_panel *panel)
 {
struct drm_panel_follower *follower;
int ret;
 
if (!panel)
-   return -EINVAL;
+   return;
 
/*
 * If you are seeing the warning below it likely means one of two 
things:
@@ -176,7 +171,7 @@ int drm_panel_unprepare(struct drm_panel *panel)
 */
if (!panel->prepared) {
dev_warn(panel->dev, "Skipping unprepare of already unprepared 
panel\n");
-   return 0;
+   return;
}
 
mutex_lock(&panel->follower_lock);
@@ -195,11 +190,8 @@ int drm_panel_unprepare(struct drm_panel *panel)
}
panel->prepared = false;
 
-   ret = 0;
 exit:
mutex_unlock(&panel->follower_lock);
-
-   return ret;
 }
 EXPORT_SYMBOL(drm_panel_unprepare);
 
@@ -209,26 +201,26 @@ EXPORT_SYMBOL(drm_panel_unprepare);
  *
  * Calling this function will cause the panel display drivers to be turned on
  * and the backlight to be enabled. Content will be visible on screen after
- * this call completes.
- *
- * Return: 0 on success or a negative error code on failure.
+ * this call completes. This function cannot fail (as it is called from the
+ * enable call chain). There will always be a call to drm_panel_disable()
+ * afterwards.
  */
-int drm_panel_enable(struct drm_panel *panel)
+void drm_panel_enable(struct drm_panel *panel)
 {
int ret;
 
if (!panel)
-   return -EINVAL;
+   return;
 
if (panel->enabled) {
dev_warn(panel->dev, "Skipping enable of already enabled 
panel\n");
-   return 0;
+   return;
}
 
if (panel->funcs && panel->funcs->enable) {
ret = panel->funcs->enable(panel);
if (ret < 0)
-   return ret;
+   return;
}
panel->enabled = true;
 
@@ -236,8 +228,6 @@ int drm_panel_enable(struct drm_panel *panel)
if (ret < 0)
DRM_DEV_INFO(panel->dev, "failed to enable backlight: %d\n",
 ret);
-
-   return 0;
 }
 EXPORT_SYMBOL(drm_panel_enable);
 
@@ -248,15 +238,13 @@ EXPORT_SYMBOL(drm_panel_enable);
  * This will typically turn off the panel's backlight or disable the display
  * drivers. For smart panels it should still be possible to communicate with
  * the integrated circuitry via any command bus after this call.
- *
- * Return: 0 on success or a negative error code o

[PATCH 3/7] drm/bridge: analogic_dp: drop panel_is_modeset

2025-03-31 Thread Dmitry Baryshkov
The dp->panel_is_modeset is now a write-only field. Drop it completely.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 +--
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  1 -
 2 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 
82dc4b01806f9728dc882b0128171838e81f21b0..704c6169116eb2601d2ad02dc7294455ceff5460
 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -964,9 +964,7 @@ static int analogix_dp_disable_psr(struct 
analogix_dp_device *dp)
  * is false, the panel will be unprepared.
  *
  * The function will disregard the current state
- * of the panel and either prepare/unprepare the panel based on @prepare. Once
- * it finishes, it will update dp->panel_is_modeset to reflect the current 
state
- * of the panel.
+ * of the panel and either prepare/unprepare the panel based on @prepare.
  */
 static int analogix_dp_prepare_panel(struct analogix_dp_device *dp,
 bool prepare)
@@ -983,12 +981,6 @@ static int analogix_dp_prepare_panel(struct 
analogix_dp_device *dp,
else
ret = drm_panel_unprepare(dp->plat_data->panel);
 
-   if (ret)
-   goto out;
-
-   dp->panel_is_modeset = prepare;
-
-out:
mutex_unlock(&dp->panel_lock);
return ret;
 }
@@ -1532,7 +1524,6 @@ analogix_dp_probe(struct device *dev, struct 
analogix_dp_plat_data *plat_data)
dp->dpms_mode = DRM_MODE_DPMS_OFF;
 
mutex_init(&dp->panel_lock);
-   dp->panel_is_modeset = false;
 
/*
 * platform dp driver need containor_of the plat_data to get
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 
774d11574b095b093ddf2818ad5b84be6605c9bf..b679d5b71d276f458d905c936160f107225bc6c5
 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -170,7 +170,6 @@ struct analogix_dp_device {
boolpsr_supported;
 
struct mutexpanel_lock;
-   boolpanel_is_modeset;
 
struct analogix_dp_plat_data *plat_data;
 };

-- 
2.39.5



[PATCH 6/7] drm/bridge: analogix_dp: ignore return values of drm_panel_* calls

2025-03-31 Thread Dmitry Baryshkov
Follow the example of other drivers and ignore return values of the
drm_panel_prepare() / unprepare() / enable() / disable() calls. There is
no possible error recovery, so the driver just logs a message.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 39 --
 1 file changed, 6 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 
f60068011008482f7b7b2edfcab5fb1b3e9e130f..c7dffdae31877ae194fc6b0a5bf21be203f7dcc4
 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -838,10 +838,7 @@ static int analogix_dp_commit(struct analogix_dp_device 
*dp)
int ret;
 
/* Keep the panel disabled while we configure video */
-   if (dp->plat_data->panel) {
-   if (drm_panel_disable(dp->plat_data->panel))
-   DRM_ERROR("failed to disable the panel\n");
-   }
+   drm_panel_disable(dp->plat_data->panel);
 
ret = analogix_dp_train_link(dp);
if (ret) {
@@ -863,13 +860,7 @@ static int analogix_dp_commit(struct analogix_dp_device 
*dp)
}
 
/* Safe to enable the panel now */
-   if (dp->plat_data->panel) {
-   ret = drm_panel_enable(dp->plat_data->panel);
-   if (ret) {
-   DRM_ERROR("failed to enable the panel\n");
-   return ret;
-   }
-   }
+   drm_panel_enable(dp->plat_data->panel);
 
/* Check whether panel supports fast training */
ret = analogix_dp_fast_link_train_detection(dp);
@@ -1136,7 +1127,6 @@ static void analogix_dp_bridge_atomic_pre_enable(struct 
drm_bridge *bridge,
struct analogix_dp_device *dp = bridge->driver_private;
struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state;
-   int ret;
 
crtc = analogix_dp_get_new_crtc(dp, old_state);
if (!crtc)
@@ -1147,11 +1137,7 @@ static void analogix_dp_bridge_atomic_pre_enable(struct 
drm_bridge *bridge,
if (old_crtc_state && old_crtc_state->self_refresh_active)
return;
 
-   if (dp->plat_data->panel) {
-   ret = drm_panel_prepare(dp->plat_data->panel);
-   if (ret)
-   DRM_ERROR("failed to prepare the panel ret = %d\n", 
ret);
-   }
+   drm_panel_prepare(dp->plat_data->panel);
 }
 
 static int analogix_dp_set_bridge(struct analogix_dp_device *dp)
@@ -1231,17 +1217,11 @@ static void analogix_dp_bridge_atomic_enable(struct 
drm_bridge *bridge,
 static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
 {
struct analogix_dp_device *dp = bridge->driver_private;
-   int ret;
 
if (dp->dpms_mode != DRM_MODE_DPMS_ON)
return;
 
-   if (dp->plat_data->panel) {
-   if (drm_panel_disable(dp->plat_data->panel)) {
-   DRM_ERROR("failed to disable the panel\n");
-   return;
-   }
-   }
+   drm_panel_disable(dp->plat_data->panel);
 
disable_irq(dp->irq);
 
@@ -1249,11 +1229,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge 
*bridge)
 
pm_runtime_put_sync(dp->dev);
 
-   if (dp->plat_data->panel) {
-   ret = drm_panel_unprepare(dp->plat_data->panel);
-   if (ret)
-   DRM_ERROR("failed to unprepare the panel ret = %d\n", 
ret);
-   }
+   drm_panel_unprepare(dp->plat_data->panel);
 
dp->fast_train_enable = false;
dp->psr_supported = false;
@@ -1678,10 +1654,7 @@ void analogix_dp_unbind(struct analogix_dp_device *dp)
analogix_dp_bridge_disable(dp->bridge);
dp->connector.funcs->destroy(&dp->connector);
 
-   if (dp->plat_data->panel) {
-   if (drm_panel_unprepare(dp->plat_data->panel))
-   DRM_ERROR("failed to turnoff the panel\n");
-   }
+   drm_panel_unprepare(dp->plat_data->panel);
 
drm_dp_aux_unregister(&dp->aux);
 

-- 
2.39.5



[PATCH 5/7] drm/bridge: analogix_dp: inline analogix_dp_prepare_panel()

2025-03-31 Thread Dmitry Baryshkov
The analogix_dp_prepare_panel() is now only calling a corresponding
drm_panel function. Inline it to simplify the code.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 43 +-
 1 file changed, 10 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 
1ec4d277fe6bb03ad9eb8451ae2af5ad5ada0978..f60068011008482f7b7b2edfcab5fb1b3e9e130f
 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -955,33 +955,6 @@ static int analogix_dp_disable_psr(struct 
analogix_dp_device *dp)
return analogix_dp_send_psr_spd(dp, &psr_vsc, true);
 }
 
-/*
- * This function is a bit of a catch-all for panel preparation, hopefully
- * simplifying the logic of functions that need to prepare/unprepare the panel
- * below.
- *
- * If @prepare is true, this function will prepare the panel. Conversely, if it
- * is false, the panel will be unprepared.
- *
- * The function will disregard the current state
- * of the panel and either prepare/unprepare the panel based on @prepare.
- */
-static int analogix_dp_prepare_panel(struct analogix_dp_device *dp,
-bool prepare)
-{
-   int ret = 0;
-
-   if (!dp->plat_data->panel)
-   return 0;
-
-   if (prepare)
-   ret = drm_panel_prepare(dp->plat_data->panel);
-   else
-   ret = drm_panel_unprepare(dp->plat_data->panel);
-
-   return ret;
-}
-
 static int analogix_dp_get_modes(struct drm_connector *connector)
 {
struct analogix_dp_device *dp = to_dp(connector);
@@ -1174,9 +1147,11 @@ static void analogix_dp_bridge_atomic_pre_enable(struct 
drm_bridge *bridge,
if (old_crtc_state && old_crtc_state->self_refresh_active)
return;
 
-   ret = analogix_dp_prepare_panel(dp, true);
-   if (ret)
-   DRM_ERROR("failed to setup the panel ret = %d\n", ret);
+   if (dp->plat_data->panel) {
+   ret = drm_panel_prepare(dp->plat_data->panel);
+   if (ret)
+   DRM_ERROR("failed to prepare the panel ret = %d\n", 
ret);
+   }
 }
 
 static int analogix_dp_set_bridge(struct analogix_dp_device *dp)
@@ -1274,9 +1249,11 @@ static void analogix_dp_bridge_disable(struct drm_bridge 
*bridge)
 
pm_runtime_put_sync(dp->dev);
 
-   ret = analogix_dp_prepare_panel(dp, false);
-   if (ret)
-   DRM_ERROR("failed to setup the panel ret = %d\n", ret);
+   if (dp->plat_data->panel) {
+   ret = drm_panel_unprepare(dp->plat_data->panel);
+   if (ret)
+   DRM_ERROR("failed to unprepare the panel ret = %d\n", 
ret);
+   }
 
dp->fast_train_enable = false;
dp->psr_supported = false;

-- 
2.39.5



Re: [PATCH 02/12] drm/i915/display: Introduce HAS_CASF for sharpness support

2025-03-31 Thread Nautiyal, Ankit K



On 3/21/2025 9:36 PM, Nemesa Garg wrote:

HAS_CASF macro will be used to check whether platform
support the content adaptive sharpness capability or
not.


Perhaps reworded to maintain imperative mood:

Add HAS_CASF macro to check..

Otherwise LGTM.

Reviewed-by: Ankit Nautiyal 



v2: Update commit message[Ankit]

Signed-off-by: Nemesa Garg 
---
  drivers/gpu/drm/i915/display/intel_display_device.h | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h 
b/drivers/gpu/drm/i915/display/intel_display_device.h
index 368b0d3417c2..09b9991beffa 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -145,6 +145,7 @@ struct intel_display_platforms {
  #define HAS_ASYNC_FLIPS(__display)(DISPLAY_VER(__display) >= 5)
  #define HAS_AS_SDP(__display) (DISPLAY_VER(__display) >= 13)
  #define HAS_BIGJOINER(__display)  (DISPLAY_VER(__display) >= 11 && 
HAS_DSC(__display))
+#define HAS_CASF(__display)(DISPLAY_VER(__display) >= 20)
  #define HAS_CDCLK_CRAWL(__display)
(DISPLAY_INFO(__display)->has_cdclk_crawl)
  #define HAS_CDCLK_SQUASH(__display)   
(DISPLAY_INFO(__display)->has_cdclk_squash)
  #define HAS_CMRR(__display)   (DISPLAY_VER(__display) >= 20)


Re: [PATCH 03/12] drm/i915/display: Add sharpness strength and winsize

2025-03-31 Thread Nautiyal, Ankit K



On 3/21/2025 9:36 PM, Nemesa Garg wrote:

register


I think this is part of the subject, need to fix this.




The strength value for sharpness is based on user input and
the winsize is based on resolution. Set the casf_enable flag
if there is a platform support and uapi strength is not zero.
Once the sharpness is enabled then just update the strength
bit of the register everytime whenever user changes the strength
as enable bit and winsize bit remains constant.

v2: Introduce get_config for casf[Ankit]

Signed-off-by: Nemesa Garg 
---
  drivers/gpu/drm/i915/Makefile |  1 +
  drivers/gpu/drm/i915/display/intel_casf.c | 99 +++
  drivers/gpu/drm/i915/display/intel_casf.h | 17 
  .../gpu/drm/i915/display/intel_casf_regs.h| 22 +
  .../drm/i915/display/intel_crtc_state_dump.c  |  7 ++
  .../drm/i915/display/intel_display_types.h|  7 ++
  drivers/gpu/drm/i915/display/skl_scaler.c |  1 +
  drivers/gpu/drm/xe/Makefile   |  1 +
  8 files changed, 155 insertions(+)
  create mode 100644 drivers/gpu/drm/i915/display/intel_casf.c
  create mode 100644 drivers/gpu/drm/i915/display/intel_casf.h
  create mode 100644 drivers/gpu/drm/i915/display/intel_casf_regs.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index c8fc271b33b7..a955960d09ec 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -230,6 +230,7 @@ i915-y += \
display/intel_bios.o \
display/intel_bo.o \
display/intel_bw.o \
+   display/intel_casf.o \
display/intel_cdclk.o \
display/intel_cmtg.o \
display/intel_color.o \
diff --git a/drivers/gpu/drm/i915/display/intel_casf.c 
b/drivers/gpu/drm/i915/display/intel_casf.c
new file mode 100644
index ..28f76b06fd8f
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_casf.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2025 Intel Corporation
+ *
+ */
+#include "i915_reg.h"
+#include "intel_casf.h"
+#include "intel_casf_regs.h"
+#include "intel_de.h"
+#include "intel_display_types.h"
+
+#define MAX_PIXELS_FOR_3_TAP_FILTER (1920 * 1080)
+#define MAX_PIXELS_FOR_5_TAP_FILTER (3840 * 2160)
+
+/**
+ * DOC: Content Adaptive Sharpness Filter (CASF)
+ *
+ * From LNL onwards the display engine based adaptive
+ * sharpening filter is supported. This helps in
+ * improving the image quality. The display hardware
+ * uses one of the pipe scaler for implementing casf.


Use CASF.

Perhaps a line can be left here before beginning a new paragraph.


+ * It works on a region of pixels depending on the


CASF works...

Apart from the nitpicks above the patch looks good to me.

Reviewed-by: Ankit Nautiyal 



+ * tap size. The coefficients are used to generate an
+ * alpha value which is used to blend the sharpened image
+ * to original image.
+ */
+
+void intel_casf_update_strength(struct intel_crtc_state *crtc_state)
+{
+   struct intel_display *display = to_intel_display(crtc_state);
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+   intel_de_rmw(display, SHARPNESS_CTL(crtc->pipe), 0,
+FILTER_STRENGTH(crtc_state->hw.casf_params.strength));
+}
+
+static void intel_casf_compute_win_size(struct intel_crtc_state *crtc_state)
+{
+   const struct drm_display_mode *mode = &crtc_state->hw.adjusted_mode;
+   u16 total_pixels = mode->hdisplay * mode->vdisplay;
+
+   if (total_pixels <= MAX_PIXELS_FOR_3_TAP_FILTER)
+   crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_3X3;
+   else if (total_pixels <= MAX_PIXELS_FOR_5_TAP_FILTER)
+   crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_5X5;
+   else
+   crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_7X7;
+}
+
+int intel_casf_compute_config(struct intel_crtc_state *crtc_state)
+{
+   struct intel_display *display = to_intel_display(crtc_state);
+
+   if (!HAS_CASF(display))
+   return 0;
+
+   if (crtc_state->uapi.sharpness_strength == 0) {
+   crtc_state->hw.casf_params.casf_enable = false;
+   crtc_state->hw.casf_params.strength = 0;
+   return 0;
+   }
+
+   crtc_state->hw.casf_params.casf_enable = true;
+
+   /*
+* HW takes a value in form (1.0 + strength) in 4.4 fixed format.
+* Strength is from 0.0-14.9375 ie from 0-239.
+* User can give value from 0-255 but is clamped to 239.
+* Ex. User gives 85 which is 5.3125 and adding 1.0 gives 6.3125.
+* 6.3125 in 4.4 format is b01100101 which is equal to 101.
+* Also 85 + 16 = 101.
+*/
+   crtc_state->hw.casf_params.strength =
+   min(crtc_state->uapi.sharpness_strength, 0xEF) + 0x10;
+
+   intel_casf_compute_win_size(crtc_state);
+
+   return 0;
+}
+
+void intel_casf_sharpness_get_config(struct intel_crtc_state *crtc_state)
+{
+   s

Re: [PATCH 05/12] drm/i915/display: Compute the scaler filter

2025-03-31 Thread Nautiyal, Ankit K



On 3/21/2025 9:36 PM, Nemesa Garg wrote:

coefficients


This is part of the subject, need to fix.

Regards,

Ankit



The sharpness property requires the use of one of the scaler
so need to set the sharpness scaler coefficient values.
These values are based on experiments and vary for different
tap value/win size. These values are normalized by taking the
sum of all values and then dividing each value with a sum.

v2: Fix ifndef header naming issue reported by kernel test robot
v3: Rename file name[Arun]
 Replace array size number with macro[Arun]
v4: Correct the register format[Jani]
 Add brief comment and expalin about file[Jani]
 Remove coefficient value from crtc_state[Jani]
v5: Fix build issue
v6: Add new function for writing coefficients[Ankit]
v7: Add cooments and add a scaler id check [Ankit]
v8: Remove casf_enable from here[Ankit]

Signed-off-by: Nemesa Garg 
Reviewed-by: Ankit Nautiyal 
---
  drivers/gpu/drm/i915/display/intel_casf.c | 120 ++
  drivers/gpu/drm/i915/display/intel_casf.h |   1 +
  .../gpu/drm/i915/display/intel_casf_regs.h|   7 +
  .../drm/i915/display/intel_display_types.h|   8 ++
  4 files changed, 136 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_casf.c 
b/drivers/gpu/drm/i915/display/intel_casf.c
index d0bb51cd4b54..eb69c449a2f5 100644
--- a/drivers/gpu/drm/i915/display/intel_casf.c
+++ b/drivers/gpu/drm/i915/display/intel_casf.c
@@ -12,6 +12,13 @@
  #define MAX_PIXELS_FOR_3_TAP_FILTER (1920 * 1080)
  #define MAX_PIXELS_FOR_5_TAP_FILTER (3840 * 2160)
  
+#define FILTER_COEFF_0_125 125

+#define FILTER_COEFF_0_25 250
+#define FILTER_COEFF_0_5 500
+#define FILTER_COEFF_1_0 1000
+#define FILTER_COEFF_0_0 0
+#define SET_POSITIVE_SIGN(x) ((x) & (~SIGN))
+
  /**
   * DOC: Content Adaptive Sharpness Filter (CASF)
   *
@@ -33,6 +40,24 @@ static const u16 sharpness_lut[] = {
73, 60, 48, 36, 24, 12, 0
  };
  
+const u16 filtercoeff_1[] = {

+   FILTER_COEFF_0_0, FILTER_COEFF_0_0, FILTER_COEFF_0_5,
+   FILTER_COEFF_1_0, FILTER_COEFF_0_5, FILTER_COEFF_0_0,
+   FILTER_COEFF_0_0,
+};
+
+const u16 filtercoeff_2[] = {
+   FILTER_COEFF_0_0, FILTER_COEFF_0_25, FILTER_COEFF_0_5,
+   FILTER_COEFF_1_0, FILTER_COEFF_0_5, FILTER_COEFF_0_25,
+   FILTER_COEFF_0_0,
+};
+
+const u16 filtercoeff_3[] = {
+   FILTER_COEFF_0_125, FILTER_COEFF_0_25, FILTER_COEFF_0_5,
+   FILTER_COEFF_1_0, FILTER_COEFF_0_5, FILTER_COEFF_0_25,
+   FILTER_COEFF_0_125,
+};
+
  void intel_filter_lut_load(struct intel_crtc *crtc,
   const struct intel_crtc_state *crtc_state)
  {
@@ -97,6 +122,8 @@ int intel_casf_compute_config(struct intel_crtc_state 
*crtc_state)
  
  	intel_casf_compute_win_size(crtc_state);
  
+	intel_casf_scaler_compute_config(crtc_state);

+
return 0;
  }
  
@@ -119,3 +146,96 @@ void intel_casf_sharpness_get_config(struct intel_crtc_state *crtc_state)

REG_FIELD_GET(FILTER_SIZE_MASK, sharp);
}
  }
+
+static int casf_coeff_tap(int i)
+{
+   return i % SCALER_FILTER_NUM_TAPS;
+}
+
+static u16 casf_coeff(struct intel_crtc_state *crtc_state, int t)
+{
+   struct scaler_filter_coeff value;
+   u16 coeff;
+
+   value = crtc_state->hw.casf_params.coeff[t];
+   coeff = SET_POSITIVE_SIGN(0) | EXPONENT(value.exp) | 
MANTISSA(value.mantissa);
+   return coeff;
+}
+
+/*
+ * 17 phase of 7 taps requires 119 coefficients in 60 dwords per set.
+ * To enable casf:  program scaler coefficients with the coeffients
+ * that are calculated and stored in hw.casf_params.coeff as per
+ * SCALER_COEFFICIENT_FORMAT
+ */
+static void intel_casf_write_coeff(struct intel_crtc_state *crtc_state)
+{
+   struct intel_display *display = to_intel_display(crtc_state);
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+   int id = crtc_state->scaler_state.scaler_id;
+   int i;
+
+   if (id != 1) {
+   drm_WARN(display->drm, 0, "Second scaler not enabled\n");
+   return;
+   }
+
+   intel_de_write_fw(display, GLK_PS_COEF_INDEX_SET(crtc->pipe, id, 0),
+ PS_COEF_INDEX_AUTO_INC);
+
+   for (i = 0; i < 17 * SCALER_FILTER_NUM_TAPS; i += 2) {
+   u32 tmp;
+   int t;
+
+   t = casf_coeff_tap(i);
+   tmp = casf_coeff(crtc_state, t);
+
+   t = casf_coeff_tap(i + 1);
+   tmp |= casf_coeff(crtc_state, t) << 16;
+
+   intel_de_write_fw(display, GLK_PS_COEF_DATA_SET(crtc->pipe, id, 
0),
+ tmp);
+   }
+}
+
+static void convert_sharpness_coef_binary(struct scaler_filter_coeff *coeff,
+ u16 coefficient)
+{
+   if (coefficient < 25) {
+   coeff->mantissa = (coefficient * 2048) / 100;
+   coeff->exp = 3;
+   } else if (coefficient < 50) {
+   coeff->mantissa = (coefficient *

Re: [PATCH 07/12] drm/i915/display: Configure the second scaler for

2025-03-31 Thread Nautiyal, Ankit K



On 3/21/2025 9:36 PM, Nemesa Garg wrote:

sharpness


This again is part of subject.



As only second scaler can be used for sharpness check if it
is available and also check if panel fitting is not enabled,
then set the sharpness as both uses pipe scaler so only one
can be enabled at a time.


This can be improved. Avoid having one long sentence for the commit message.

Regards,

Ankit




v2: Add the panel fitting check before enabling sharpness
v3: Reframe commit message[Arun]
v4: Replace string based comparison with plane_state[Jani]
v5: Rebase
v6: Fix build issue
v7: Remove scaler id from verify_crtc_state[Ankit]
v8: Change the patch title. Add code comment.
 Move the config part in patch#6. [Ankit]
v9: Refactor the patch[Ankit]

Signed-off-by: Nemesa Garg 
---
  drivers/gpu/drm/i915/display/intel_casf.c|  8 +++
  drivers/gpu/drm/i915/display/intel_casf.h|  1 +
  drivers/gpu/drm/i915/display/intel_display.c |  4 +++-
  drivers/gpu/drm/i915/display/skl_scaler.c| 25 +++-
  4 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_casf.c 
b/drivers/gpu/drm/i915/display/intel_casf.c
index 4c41a41872bd..367a73a91ae6 100644
--- a/drivers/gpu/drm/i915/display/intel_casf.c
+++ b/drivers/gpu/drm/i915/display/intel_casf.c
@@ -148,6 +148,14 @@ void intel_casf_sharpness_get_config(struct 
intel_crtc_state *crtc_state)
}
  }
  
+bool intel_casf_needs_scaler(const struct intel_crtc_state *crtc_state)

+{
+   if (crtc_state->hw.casf_params.casf_enable)
+   return true;
+
+   return false;
+}
+
  static int casf_coeff_tap(int i)
  {
return i % SCALER_FILTER_NUM_TAPS;
diff --git a/drivers/gpu/drm/i915/display/intel_casf.h 
b/drivers/gpu/drm/i915/display/intel_casf.h
index 381d5e10c70d..026a2b8348df 100644
--- a/drivers/gpu/drm/i915/display/intel_casf.h
+++ b/drivers/gpu/drm/i915/display/intel_casf.h
@@ -17,5 +17,6 @@ void intel_casf_sharpness_get_config(struct intel_crtc_state 
*crtc_state);
  void intel_filter_lut_load(struct intel_crtc *crtc,
   const struct intel_crtc_state *crtc_state);
  void intel_casf_scaler_compute_config(struct intel_crtc_state *crtc_state);
+bool intel_casf_needs_scaler(const struct intel_crtc_state *crtc_state);
  
  #endif /* __INTEL_CASF_H__ */

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index b852ffe94a10..4ffe738ad725 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -60,6 +60,7 @@
  #include "intel_audio.h"
  #include "intel_bo.h"
  #include "intel_bw.h"
+#include "intel_casf.h"
  #include "intel_cdclk.h"
  #include "intel_clock_gating.h"
  #include "intel_color.h"
@@ -4225,7 +4226,8 @@ static int intel_crtc_atomic_check(struct 
intel_atomic_state *state,
  
  	if (DISPLAY_VER(display) >= 9) {

if (intel_crtc_needs_modeset(crtc_state) ||
-   intel_crtc_needs_fastset(crtc_state)) {
+   intel_crtc_needs_fastset(crtc_state) ||
+   intel_casf_needs_scaler(crtc_state)) {
ret = skl_update_scaler_crtc(crtc_state);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c 
b/drivers/gpu/drm/i915/display/skl_scaler.c
index 39fc537e54f0..d816dae9cec4 100644
--- a/drivers/gpu/drm/i915/display/skl_scaler.c
+++ b/drivers/gpu/drm/i915/display/skl_scaler.c
@@ -5,6 +5,7 @@
  
  #include "i915_drv.h"

  #include "i915_reg.h"
+#include "intel_casf.h"
  #include "intel_casf_regs.h"
  #include "intel_de.h"
  #include "intel_display_trace.h"
@@ -272,7 +273,8 @@ int skl_update_scaler_crtc(struct intel_crtc_state 
*crtc_state)
 drm_rect_width(&crtc_state->pipe_src),
 drm_rect_height(&crtc_state->pipe_src),
 width, height, NULL, 0,
-crtc_state->pch_pfit.enabled);
+crtc_state->pch_pfit.enabled ||
+intel_casf_needs_scaler(crtc_state));
  }
  
  /**

@@ -311,7 +313,9 @@ int skl_update_scaler_plane(struct intel_crtc_state 
*crtc_state,
  }
  
  static int intel_allocate_scaler(struct intel_crtc_scaler_state *scaler_state,

-struct intel_crtc *crtc)
+struct intel_crtc *crtc,
+struct intel_plane_state *plane_state,
+bool casf_scaler)
  {
int i;
  
@@ -319,6 +323,10 @@ static int intel_allocate_scaler(struct intel_crtc_scaler_state *scaler_state,

if (scaler_state->scalers[i].in_use)
continue;
  
+		/* CASF needs second scaler */

+   if (!plane_state && casf_scaler && i != 1)
+   continue;
+
   

[RFC v3 04/14] drm/sched: Clarify locked section in drm_sched_rq_select_entity_fifo

2025-03-31 Thread Tvrtko Ursulin
Rq->lock only protects the tree walk so lets move the rest out.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
---
 drivers/gpu/drm/scheduler/sched_main.c | 31 ++
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index f593b88ab02c..357133e6d4d0 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -326,29 +326,32 @@ static struct drm_sched_entity *
 drm_sched_rq_select_entity_fifo(struct drm_gpu_scheduler *sched,
struct drm_sched_rq *rq)
 {
+   struct drm_sched_entity *entity = NULL;
struct rb_node *rb;
 
spin_lock(&rq->lock);
for (rb = rb_first_cached(&rq->rb_tree_root); rb; rb = rb_next(rb)) {
-   struct drm_sched_entity *entity;
-
entity = rb_entry(rb, struct drm_sched_entity, rb_tree_node);
-   if (drm_sched_entity_is_ready(entity)) {
-   /* If we can't queue yet, preserve the current entity in
-* terms of fairness.
-*/
-   if (!drm_sched_can_queue(sched, entity)) {
-   spin_unlock(&rq->lock);
-   return ERR_PTR(-ENOSPC);
-   }
-
-   reinit_completion(&entity->entity_idle);
+   if (drm_sched_entity_is_ready(entity))
break;
-   }
+   else
+   entity = NULL;
}
spin_unlock(&rq->lock);
 
-   return rb ? rb_entry(rb, struct drm_sched_entity, rb_tree_node) : NULL;
+   if (!entity)
+   return NULL;
+
+   /*
+* If scheduler cannot take more jobs signal the caller to not consider
+* lower priority queues.
+*/
+   if (!drm_sched_can_queue(sched, entity))
+   return ERR_PTR(-ENOSPC);
+
+   reinit_completion(&entity->entity_idle);
+
+   return entity;
 }
 
 /**
-- 
2.48.0



Re: [PATCH v3 1/2] arm64: dts: qcom: x1e78100-t14s: add hpd gpio to eDP panel

2025-03-31 Thread Dmitry Baryshkov
On Tue, 1 Apr 2025 at 00:38, Christopher Obbard
 wrote:
>
> Hi Dmitry,
>
> On Mon, 31 Mar 2025 at 17:49, Dmitry Baryshkov
>  wrote:
> >
> > On 31/03/2025 18:39, Christopher Obbard wrote:
> > > Hi Johan,
> > >
> > > On Mon, 31 Mar 2025 at 09:50, Johan Hovold  wrote:
> > >>
> > >> On Thu, Mar 27, 2025 at 04:56:53PM +, Christopher Obbard wrote:
> > >>> The eDP panel has an HPD GPIO. Describe it in the device tree
> > >>> for the generic T14s model, as the HPD GPIO property is used in
> > >>> both the OLED and LCD models which inherit this device tree.
> > >>
> > >> AFAICT, this patch is not correct as the hotplug detect signal is
> > >> connected directly to the display controller on (these) Qualcomm SoCs
> > >> and is already handled by its driver.
> > >>
> > >> Describing it as you do here leads to less accurate delays, see commits:
> > >>
> > >>  2327b13d6c47 ("drm/panel-edp: Take advantage of 
> > >> wait_hpd_asserted() in struct drm_dp_aux").
> > >>  3b5765df375c ("drm/panel: atna33xc20: Take advantage of 
> > >> wait_hpd_asserted() in struct drm_dp_aux")
> > >>
> > >> Perhaps you lose some other functionality too.
> > >>
> > >>> Reviewed-by: Bryan O'Donoghue 
> > >>> Signed-off-by: Christopher Obbard 
> > >>> ---
> > >>>   arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi | 11 
> > >>> +++
> > >>>   1 file changed, 11 insertions(+)
> > >>>
> > >>> diff --git 
> > >>> a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi 
> > >>> b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > >>> index 
> > >>> 962fb050c55c4fd33f480a21a8c47a484d0c82b8..46c73f5c039ed982b553636cf8c4237a20ba7687
> > >>>  100644
> > >>> --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > >>> +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > >>> @@ -980,8 +980,12 @@ &mdss_dp3 {
> > >>>aux-bus {
> > >>>panel: panel {
> > >>>compatible = "edp-panel";
> > >>> + hpd-gpios = <&tlmm 119 GPIO_ACTIVE_HIGH>;
> > >>>power-supply = <&vreg_edp_3p3>;
> > >>>
> > >>> + pinctrl-0 = <&edp_hpd_n_default>;
> > >>> + pinctrl-names = "default";
> > >>> +
> > >>>port {
> > >>>edp_panel_in: endpoint {
> > >>>remote-endpoint = 
> > >>> <&mdss_dp3_out>;
> > >>> @@ -1286,6 +1290,13 @@ hall_int_n_default: hall-int-n-state {
> > >>>bias-disable;
> > >>>};
> > >>>
> > >>> + edp_hpd_n_default: edp-hpd-n-state {
> > >>> + pins = "gpio119";
> > >>> + function = "gpio";
> > >>> + drive-strength = <2>;
> > >>> + bias-pull-up;
> > >>> + };
> > >>
> > >> I checked the firmware configuration for this pin on my T14s, which
> > >> does not match what you have here. Instead the function is set to
> > >> "edp0_hot" which forwards the signal to the display controller which
> > >> already handles the signal on panel power on. (And there is also no
> > >> internal pull up enabled).
> > >>
> > >> We may want to describe this pin configuration somewhere, but that's a
> > >> separate issue.
> > >
> > > Thanks for your review, I will send another version in coming days and
> > > drop this first patch (adding hpd to the T14s DTSI).
> > >
> > > As a consequence I will need to add no-hpd property to the panel node.
> > No, you won't. There is a HPD line and it is routed to the DP controller.
>
> OK, I think I misunderstand what Johan said. After taking some time to
> think about it in more detail:
> - The first commit will be changed so that the hpd GPIO will be added
> to the X1E DP controller instead of the panel. grepping the source for
> dp_hot_plug_det shows me how to do that. This part is clear.
>
> - The panel node in the generic T14s DTSI should not have the
> hpd-gpios property / pinctrl set.
>
> - The panel node should not have the hpd-gpios property / pinctrl set.

LGTM. Use sc8180x-primus as an example

>
> I hope I understand that correctly. I will send a new series in the
> morning unless there is any objection.


-- 
With best wishes
Dmitry


Re: [PATCH 08/12] drm/i915/display: Compare the sharpness state

2025-03-31 Thread Nautiyal, Ankit K



On 3/21/2025 9:36 PM, Nemesa Garg wrote:

Compare the sharpness win_size, strength and enable bits

Signed-off-by: Nemesa Garg 
---
  drivers/gpu/drm/i915/display/intel_display.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 4ffe738ad725..f807915e0fee 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5276,6 +5276,9 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
  
  		PIPE_CONF_CHECK_I(scaler_state.scaler_id);

PIPE_CONF_CHECK_I(pixel_rate);
+   PIPE_CONF_CHECK_BOOL(hw.casf_params.casf_enable);
+   PIPE_CONF_CHECK_I(hw.casf_params.win_size);
+   PIPE_CONF_CHECK_I(hw.casf_params.strength);


This can be clubbed with Patch#10 where we compute, and get the config 
for CASF.



Regards,

Ankit

  
  		PIPE_CONF_CHECK_X(gamma_mode);

if (display->platform.cherryview)


Re: [PATCH 10/12] drm/i915/display: Write and read back the casf registers

2025-03-31 Thread Nautiyal, Ankit K



On 3/21/2025 9:36 PM, Nemesa Garg wrote:

Write the casf registers bits to enable the sharpness


Hmm, there is no write here. We are setting the configuration for CASF 
and capturing it in crtc_state, and we are getting the configuration 
after a read back.


Also, as mentioned, in previous patch, the compare part can be clubbed here.

So we will have setting the config, getting the config and comparison in 
this patch.



Regards,

Ankit


and to compute the strength of casf using casf_compute_config.
Also verify whether the enable bit is set or not and strength
value is correctly updated.

v2: Update subject[Ankit]

Signed-off-by: Nemesa Garg 
---
  drivers/gpu/drm/i915/display/intel_display.c |  4 
  drivers/gpu/drm/i915/display/skl_scaler.c| 18 --
  2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index f807915e0fee..d6691cb07173 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4224,6 +4224,10 @@ static int intel_crtc_atomic_check(struct 
intel_atomic_state *state,
return ret;
}
  
+	ret = intel_casf_compute_config(crtc_state);

+   if (ret)
+   return ret;
+
if (DISPLAY_VER(display) >= 9) {
if (intel_crtc_needs_modeset(crtc_state) ||
intel_crtc_needs_fastset(crtc_state) ||
diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c 
b/drivers/gpu/drm/i915/display/skl_scaler.c
index 93a847c05535..6ddc111d5c29 100644
--- a/drivers/gpu/drm/i915/display/skl_scaler.c
+++ b/drivers/gpu/drm/i915/display/skl_scaler.c
@@ -964,16 +964,22 @@ void skl_scaler_get_config(struct intel_crtc_state 
*crtc_state)
continue;
  
  		id = i;

-   crtc_state->pch_pfit.enabled = true;
+
+   if (HAS_CASF(display) && id == 1)
+   intel_casf_sharpness_get_config(crtc_state);
+
+   if (!crtc_state->hw.casf_params.casf_enable)
+   crtc_state->pch_pfit.enabled = true;
  
  		pos = intel_de_read(display, SKL_PS_WIN_POS(crtc->pipe, i));

size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, i));
  
-		drm_rect_init(&crtc_state->pch_pfit.dst,

- REG_FIELD_GET(PS_WIN_XPOS_MASK, pos),
- REG_FIELD_GET(PS_WIN_YPOS_MASK, pos),
- REG_FIELD_GET(PS_WIN_XSIZE_MASK, size),
- REG_FIELD_GET(PS_WIN_YSIZE_MASK, size));
+   if (!crtc_state->hw.casf_params.casf_enable)
+   drm_rect_init(&crtc_state->pch_pfit.dst,
+ REG_FIELD_GET(PS_WIN_XPOS_MASK, pos),
+ REG_FIELD_GET(PS_WIN_YPOS_MASK, pos),
+ REG_FIELD_GET(PS_WIN_XSIZE_MASK, size),
+ REG_FIELD_GET(PS_WIN_YSIZE_MASK, size));
  
  		scaler_state->scalers[i].in_use = true;

break;


[PATCH 1/7] drm/bridge: analogix_dp: drop extra calls to analogix_dp_prepare_panel()

2025-03-31 Thread Dmitry Baryshkov
The analogix_dp_prepare_panel() returns immediately if there is no
attached panel. Drop several calls to this function which are performed
when dp->plat_data->panel is NULL.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 22 +-
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 
042154e2d8ccd74ac2dc27fe527e810a50e08a09..ab1cfc340aa95bbf13fe021bd33227b565a5458d
 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1005,17 +1005,11 @@ static int analogix_dp_get_modes(struct drm_connector 
*connector)
 {
struct analogix_dp_device *dp = to_dp(connector);
const struct drm_edid *drm_edid;
-   int ret, num_modes = 0;
+   int num_modes = 0;
 
if (dp->plat_data->panel) {
num_modes += drm_panel_get_modes(dp->plat_data->panel, 
connector);
} else {
-   ret = analogix_dp_prepare_panel(dp, true, false);
-   if (ret) {
-   DRM_ERROR("Failed to prepare panel (%d)\n", ret);
-   return 0;
-   }
-
drm_edid = drm_edid_read_ddc(connector, &dp->aux.ddc);
 
drm_edid_connector_update(&dp->connector, drm_edid);
@@ -1024,10 +1018,6 @@ static int analogix_dp_get_modes(struct drm_connector 
*connector)
num_modes += 
drm_edid_connector_add_modes(&dp->connector);
drm_edid_free(drm_edid);
}
-
-   ret = analogix_dp_prepare_panel(dp, false, false);
-   if (ret)
-   DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
}
 
if (dp->plat_data->get_modes)
@@ -1087,19 +1077,9 @@ analogix_dp_detect(struct drm_connector *connector, bool 
force)
if (dp->plat_data->panel)
return connector_status_connected;
 
-   ret = analogix_dp_prepare_panel(dp, true, false);
-   if (ret) {
-   DRM_ERROR("Failed to prepare panel (%d)\n", ret);
-   return connector_status_disconnected;
-   }
-
if (!analogix_dp_detect_hpd(dp))
status = connector_status_connected;
 
-   ret = analogix_dp_prepare_panel(dp, false, false);
-   if (ret)
-   DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
-
return status;
 }
 

-- 
2.39.5



RE: [PATCH 09/12] drm/i915/display: Set a scaler mode

2025-03-31 Thread Garg, Nemesa


> -Original Message-
> From: Nautiyal, Ankit K 
> Sent: Tuesday, April 1, 2025 11:07 AM
> To: Garg, Nemesa ; intel-...@lists.freedesktop.org;
> intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Subject: Re: [PATCH 09/12] drm/i915/display: Set a scaler mode
> 
> 
> On 3/21/2025 9:36 PM, Nemesa Garg wrote:
> > Set the mode of scaler to HQ for casf.
> >
> > Signed-off-by: Nemesa Garg 
> > ---
> >   drivers/gpu/drm/i915/display/skl_scaler.c | 3 +++
> >   1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c
> > b/drivers/gpu/drm/i915/display/skl_scaler.c
> > index d816dae9cec4..93a847c05535 100644
> > --- a/drivers/gpu/drm/i915/display/skl_scaler.c
> > +++ b/drivers/gpu/drm/i915/display/skl_scaler.c
> > @@ -392,6 +392,9 @@ static int intel_atomic_setup_scaler(struct
> intel_crtc_state *crtc_state,
> >  "Cannot find scaler for %s:%d\n", name, idx))
> > return -EINVAL;
> >
> > +   if (casf_scaler)
> > +   mode = SKL_PS_SCALER_MODE_HQ;
> 
> I am not very sure, if we need this. Couldn't find any where in the Spec. Can
> you check if this is really required.
> 
> If this is indeed required then would be better to document the reasoning.
> 
> Regards,
> 
> Ankit
> 
This patch is not required. I will remove it.

Regards,
Nemesa
> > +
> > /* set scaler mode */
> > if (plane_state && plane_state->hw.fb &&
> > plane_state->hw.fb->format->is_yuv &&


Re: [PATCH 11/12] drm/i915/display: Enable/disable casf

2025-03-31 Thread Nautiyal, Ankit K



On 3/21/2025 9:36 PM, Nemesa Garg wrote:

To enable or disable the sharpness check the
casf_enable flag. While enabling the sharpness
write the programmable coefficients, sharpness
register bits and also enable the scaler.
Load the filter lut value which needs to be done
one time while enabling the sharpness.

v2: Introduce casf_enable here[Ankit]

Signed-off-by: Nemesa Garg 


Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/i915/display/intel_casf.c| 27 
  drivers/gpu/drm/i915/display/intel_casf.h|  2 ++
  drivers/gpu/drm/i915/display/intel_display.c | 27 
  3 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_casf.c 
b/drivers/gpu/drm/i915/display/intel_casf.c
index 367a73a91ae6..58fa57596457 100644
--- a/drivers/gpu/drm/i915/display/intel_casf.c
+++ b/drivers/gpu/drm/i915/display/intel_casf.c
@@ -248,3 +248,30 @@ void intel_casf_scaler_compute_config(struct 
intel_crtc_state *crtc_state)
  filter_coeff[i]);
}
  }
+
+void intel_casf_enable(struct intel_crtc_state *crtc_state)
+{
+   struct intel_display *display = to_intel_display(crtc_state);
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+   u32 sharpness_ctl;
+
+   intel_filter_lut_load(crtc, crtc_state);
+
+   intel_casf_write_coeff(crtc_state);
+
+   sharpness_ctl = FILTER_EN | 
FILTER_STRENGTH(crtc_state->hw.casf_params.strength);
+
+   sharpness_ctl |= crtc_state->hw.casf_params.win_size;
+
+   intel_de_write(display, SHARPNESS_CTL(crtc->pipe), sharpness_ctl);
+
+   skl_scaler_setup_casf(crtc_state);
+}
+
+void intel_casf_disable(const struct intel_crtc_state *crtc_state)
+{
+   struct intel_display *display = to_intel_display(crtc_state);
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+   intel_de_write(display, SHARPNESS_CTL(crtc->pipe), 0);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_casf.h 
b/drivers/gpu/drm/i915/display/intel_casf.h
index 026a2b8348df..301a9fbd930f 100644
--- a/drivers/gpu/drm/i915/display/intel_casf.h
+++ b/drivers/gpu/drm/i915/display/intel_casf.h
@@ -18,5 +18,7 @@ void intel_filter_lut_load(struct intel_crtc *crtc,
   const struct intel_crtc_state *crtc_state);
  void intel_casf_scaler_compute_config(struct intel_crtc_state *crtc_state);
  bool intel_casf_needs_scaler(const struct intel_crtc_state *crtc_state);
+void intel_casf_enable(struct intel_crtc_state *crtc_state);
+void intel_casf_disable(const struct intel_crtc_state *crtc_state);
  
  #endif /* __INTEL_CASF_H__ */

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index d6691cb07173..cda8a4fed7bc 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1036,6 +1036,25 @@ static bool audio_disabling(const struct 
intel_crtc_state *old_crtc_state,
 memcmp(old_crtc_state->eld, new_crtc_state->eld, 
MAX_ELD_BYTES) != 0);
  }
  
+static bool intel_casf_enabling(const struct intel_crtc_state *new_crtc_state,

+   const struct intel_crtc_state *old_crtc_state)
+{
+   if (!new_crtc_state->hw.active)
+   return false;
+
+   return is_enabling(hw.casf_params.casf_enable, old_crtc_state, 
new_crtc_state);
+}
+
+static bool intel_casf_disabling(const struct intel_crtc_state *new_crtc_state,
+const struct intel_crtc_state *old_crtc_state)
+{
+   if (!new_crtc_state->hw.active)
+   return false;
+
+   return (old_crtc_state->hw.casf_params.casf_enable &&
+   !new_crtc_state->hw.casf_params.casf_enable);
+}
+
  #undef is_disabling
  #undef is_enabling
  
@@ -1183,6 +1202,9 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,

if (audio_disabling(old_crtc_state, new_crtc_state))
intel_encoders_audio_disable(state, crtc);
  
+	if (intel_casf_disabling(old_crtc_state, new_crtc_state))

+   intel_casf_disable(new_crtc_state);
+
intel_drrs_deactivate(old_crtc_state);
  
  	intel_psr_pre_plane_update(state, crtc);

@@ -6699,6 +6721,11 @@ static void intel_pre_update_crtc(struct 
intel_atomic_state *state,
intel_vrr_set_transcoder_timings(new_crtc_state);
}
  
+	if (intel_casf_enabling(new_crtc_state, old_crtc_state))

+   intel_casf_enable(new_crtc_state);
+   else if (new_crtc_state->hw.casf_params.strength != 
old_crtc_state->hw.casf_params.strength)
+   intel_casf_update_strength(new_crtc_state);
+
intel_fbc_update(state, crtc);
  
  	drm_WARN_ON(display->drm, !intel_display_power_is_enabled(display, POWER_DOMAIN_DC_OFF));


[PATCH 6.6 3/3] drm/amd/display: Don't write DP_MSTM_CTRL after LT

2025-03-31 Thread Thadeu Lima de Souza Cascardo
From: Wayne Lin 

[ Upstream commit bc068194f548ef1f230d96c4398046bf59165992 ]

[Why]
Observe after suspend/resme, we can't light up mst monitors under specific
mst hub. The reason is that driver still writes DPCD DP_MSTM_CTRL after LT.
It's forbidden even we write the same value for that dpcd register.

[How]
We already resume the mst branch device dpcd settings during
resume_mst_branch_status(). Leverage drm_dp_mst_topology_queue_probe() to
only probe the topology, not calling drm_dp_mst_topology_mgr_resume() which
will set DP_MSTM_CTRL as well.

Reviewed-by: Jerry Zuo 
Change-Id: I879e9f2e53dfb6fa28a33b6202a5402945ae91c5
Signed-off-by: Wayne Lin 
Signed-off-by: Zaeem Mohamed 
Tested-by: Daniel Wheeler 
Signed-off-by: Alex Deucher 
[cascardo: adjust context in local declarations]
Signed-off-by: Thadeu Lima de Souza Cascardo 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c| 16 
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 986ee37688c1..2b7f98a2e36f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2825,8 +2825,7 @@ static int dm_resume(void *handle)
struct dm_atomic_state *dm_state = 
to_dm_atomic_state(dm->atomic_obj.state);
enum dc_connection_type new_connection_type = dc_connection_none;
struct dc_state *dc_state;
-   int i, r, j, ret;
-   bool need_hotplug = false;
+   int i, r, j;
 
if (amdgpu_in_reset(adev)) {
dc_state = dm->cached_dc_state;
@@ -3003,23 +3002,16 @@ static int dm_resume(void *handle)
aconnector->mst_root)
continue;
 
-   ret = drm_dp_mst_topology_mgr_resume(&aconnector->mst_mgr, 
true);
-
-   if (ret < 0) {
-   dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx,
-   aconnector->dc_link);
-   need_hotplug = true;
-   }
+   drm_dp_mst_topology_queue_probe(&aconnector->mst_mgr);
}
drm_connector_list_iter_end(&iter);
 
-   if (need_hotplug)
-   drm_kms_helper_hotplug_event(ddev);
-
amdgpu_dm_irq_resume_late(adev);
 
amdgpu_dm_smu_write_watermarks_table(adev);
 
+   drm_kms_helper_hotplug_event(ddev);
+
return 0;
 }
 
-- 
2.47.2



[RFC v3 07/14] drm/sched: Consolidate entity run queue management

2025-03-31 Thread Tvrtko Ursulin
Move the code dealing with entities entering and exiting run queues to
helpers to logically separate it from jobs entering and exiting entities.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
---
 drivers/gpu/drm/scheduler/sched_entity.c   | 60 ++-
 drivers/gpu/drm/scheduler/sched_internal.h |  8 +-
 drivers/gpu/drm/scheduler/sched_main.c | 87 +++---
 3 files changed, 83 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_entity.c 
b/drivers/gpu/drm/scheduler/sched_entity.c
index bbb7f3d3e3e8..8362184fe431 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -469,19 +469,9 @@ drm_sched_job_dependency(struct drm_sched_job *job,
return NULL;
 }
 
-static ktime_t
-drm_sched_rq_get_rr_deadline(struct drm_sched_rq *rq)
-{
-   lockdep_assert_held(&rq->lock);
-
-   rq->rr_deadline = ktime_add_ns(rq->rr_deadline, 1);
-
-   return rq->rr_deadline;
-}
-
 struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
 {
-   struct drm_sched_job *sched_job, *next_job;
+   struct drm_sched_job *sched_job;
 
sched_job = drm_sched_entity_queue_peek(entity);
if (!sched_job)
@@ -512,27 +502,7 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct 
drm_sched_entity *entity)
 
spsc_queue_pop(&entity->job_queue);
 
-   /*
-* Update the entity's location in the min heap according to
-* the timestamp of the next job, if any.
-*/
-   next_job = drm_sched_entity_queue_peek(entity);
-   if (next_job) {
-   struct drm_sched_rq *rq;
-   ktime_t ts;
-
-   if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
-   ts = next_job->submit_ts;
-   else
-   ts = drm_sched_rq_get_rr_deadline(rq);
-
-   spin_lock(&entity->lock);
-   rq = entity->rq;
-   spin_lock(&rq->lock);
-   drm_sched_rq_update_fifo_locked(entity, rq, ts);
-   spin_unlock(&rq->lock);
-   spin_unlock(&entity->lock);
-   }
+   drm_sched_rq_pop_entity(entity);
 
/* Jobs and entities might have different lifecycles. Since we're
 * removing the job from the entities queue, set the jobs entity pointer
@@ -614,30 +584,10 @@ void drm_sched_entity_push_job(struct drm_sched_job 
*sched_job)
/* first job wakes up scheduler */
if (first) {
struct drm_gpu_scheduler *sched;
-   struct drm_sched_rq *rq;
 
-   /* Add the entity to the run queue */
-   spin_lock(&entity->lock);
-   if (entity->stopped) {
-   spin_unlock(&entity->lock);
-
-   DRM_ERROR("Trying to push to a killed entity\n");
-   return;
-   }
-
-   rq = entity->rq;
-   sched = rq->sched;
-
-   spin_lock(&rq->lock);
-   drm_sched_rq_add_entity(rq, entity);
-   if (drm_sched_policy == DRM_SCHED_POLICY_RR)
-   submit_ts = drm_sched_rq_get_rr_deadline(rq);
-   drm_sched_rq_update_fifo_locked(entity, rq, submit_ts);
-
-   spin_unlock(&rq->lock);
-   spin_unlock(&entity->lock);
-
-   drm_sched_wakeup(sched);
+   sched = drm_sched_rq_add_entity(entity, submit_ts);
+   if (sched)
+   drm_sched_wakeup(sched);
}
 }
 EXPORT_SYMBOL(drm_sched_entity_push_job);
diff --git a/drivers/gpu/drm/scheduler/sched_internal.h 
b/drivers/gpu/drm/scheduler/sched_internal.h
index 599cf6e1bb74..8e7e477bace3 100644
--- a/drivers/gpu/drm/scheduler/sched_internal.h
+++ b/drivers/gpu/drm/scheduler/sched_internal.h
@@ -12,13 +12,11 @@ extern int drm_sched_policy;
 
 void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
 
-void drm_sched_rq_add_entity(struct drm_sched_rq *rq,
-struct drm_sched_entity *entity);
+struct drm_gpu_scheduler *
+drm_sched_rq_add_entity(struct drm_sched_entity *entity, ktime_t ts);
 void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
struct drm_sched_entity *entity);
-
-void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity,
-struct drm_sched_rq *rq, ktime_t ts);
+void drm_sched_rq_pop_entity(struct drm_sched_entity *entity);
 
 void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
 struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity 
*entity);
diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index e931a9b91083..8736c7cd3ddd 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -150,15 +150,18 @@ static __always_inline 

[RFC v3 06/14] drm/sched: Implement RR via FIFO

2025-03-31 Thread Tvrtko Ursulin
Round-robin being the non-default policy and unclear how much it is used,
we can notice that it can be implemented using the FIFO data structures if
we only invent a fake submit timestamp which is monotonically increasing
inside drm_sched_rq instances.

So instead of remembering which was the last entity the scheduler worker
picked, we can bump the picked one to the bottom of the tree, achieving
the same round-robin behaviour.

Advantage is that we can consolidate to a single code path and remove a
bunch of code. Downside is round-robin mode now needs to lock on the job
pop path but that should not be visible.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
---
 drivers/gpu/drm/scheduler/sched_entity.c | 45 --
 drivers/gpu/drm/scheduler/sched_main.c   | 76 ++--
 include/drm/gpu_scheduler.h  |  5 +-
 3 files changed, 36 insertions(+), 90 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_entity.c 
b/drivers/gpu/drm/scheduler/sched_entity.c
index 9b0122e99b44..bbb7f3d3e3e8 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -469,9 +469,19 @@ drm_sched_job_dependency(struct drm_sched_job *job,
return NULL;
 }
 
+static ktime_t
+drm_sched_rq_get_rr_deadline(struct drm_sched_rq *rq)
+{
+   lockdep_assert_held(&rq->lock);
+
+   rq->rr_deadline = ktime_add_ns(rq->rr_deadline, 1);
+
+   return rq->rr_deadline;
+}
+
 struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
 {
-   struct drm_sched_job *sched_job;
+   struct drm_sched_job *sched_job, *next_job;
 
sched_job = drm_sched_entity_queue_peek(entity);
if (!sched_job)
@@ -506,21 +516,22 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct 
drm_sched_entity *entity)
 * Update the entity's location in the min heap according to
 * the timestamp of the next job, if any.
 */
-   if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) {
-   struct drm_sched_job *next;
+   next_job = drm_sched_entity_queue_peek(entity);
+   if (next_job) {
+   struct drm_sched_rq *rq;
+   ktime_t ts;
 
-   next = drm_sched_entity_queue_peek(entity);
-   if (next) {
-   struct drm_sched_rq *rq;
+   if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
+   ts = next_job->submit_ts;
+   else
+   ts = drm_sched_rq_get_rr_deadline(rq);
 
-   spin_lock(&entity->lock);
-   rq = entity->rq;
-   spin_lock(&rq->lock);
-   drm_sched_rq_update_fifo_locked(entity, rq,
-   next->submit_ts);
-   spin_unlock(&rq->lock);
-   spin_unlock(&entity->lock);
-   }
+   spin_lock(&entity->lock);
+   rq = entity->rq;
+   spin_lock(&rq->lock);
+   drm_sched_rq_update_fifo_locked(entity, rq, ts);
+   spin_unlock(&rq->lock);
+   spin_unlock(&entity->lock);
}
 
/* Jobs and entities might have different lifecycles. Since we're
@@ -619,9 +630,9 @@ void drm_sched_entity_push_job(struct drm_sched_job 
*sched_job)
 
spin_lock(&rq->lock);
drm_sched_rq_add_entity(rq, entity);
-
-   if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
-   drm_sched_rq_update_fifo_locked(entity, rq, submit_ts);
+   if (drm_sched_policy == DRM_SCHED_POLICY_RR)
+   submit_ts = drm_sched_rq_get_rr_deadline(rq);
+   drm_sched_rq_update_fifo_locked(entity, rq, submit_ts);
 
spin_unlock(&rq->lock);
spin_unlock(&entity->lock);
diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index 600904271b01..e931a9b91083 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -190,7 +190,6 @@ static void drm_sched_rq_init(struct drm_gpu_scheduler 
*sched,
spin_lock_init(&rq->lock);
INIT_LIST_HEAD(&rq->entities);
rq->rb_tree_root = RB_ROOT_CACHED;
-   rq->current_entity = NULL;
rq->sched = sched;
 }
 
@@ -236,74 +235,13 @@ void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
atomic_dec(rq->sched->score);
list_del_init(&entity->list);
 
-   if (rq->current_entity == entity)
-   rq->current_entity = NULL;
-
-   if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
-   drm_sched_rq_remove_fifo_locked(entity, rq);
+   drm_sched_rq_remove_fifo_locked(entity, rq);
 
spin_unlock(&rq->lock);
 }
 
 /**
- * drm_sched_rq_select_entity_rr - Select an entity which could provide a job 
to run
- *

[RFC v3 05/14] drm/sched: Consolidate drm_sched_rq_select_entity_rr

2025-03-31 Thread Tvrtko Ursulin
Extract out two copies of the identical code to function epilogue to make
it smaller and more readable.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
---
 drivers/gpu/drm/scheduler/sched_main.c | 48 +++---
 1 file changed, 20 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index 357133e6d4d0..600904271b01 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -268,38 +268,14 @@ drm_sched_rq_select_entity_rr(struct drm_gpu_scheduler 
*sched,
entity = rq->current_entity;
if (entity) {
list_for_each_entry_continue(entity, &rq->entities, list) {
-   if (drm_sched_entity_is_ready(entity)) {
-   /* If we can't queue yet, preserve the current
-* entity in terms of fairness.
-*/
-   if (!drm_sched_can_queue(sched, entity)) {
-   spin_unlock(&rq->lock);
-   return ERR_PTR(-ENOSPC);
-   }
-
-   rq->current_entity = entity;
-   reinit_completion(&entity->entity_idle);
-   spin_unlock(&rq->lock);
-   return entity;
-   }
+   if (drm_sched_entity_is_ready(entity))
+   goto found;
}
}
 
list_for_each_entry(entity, &rq->entities, list) {
-   if (drm_sched_entity_is_ready(entity)) {
-   /* If we can't queue yet, preserve the current entity in
-* terms of fairness.
-*/
-   if (!drm_sched_can_queue(sched, entity)) {
-   spin_unlock(&rq->lock);
-   return ERR_PTR(-ENOSPC);
-   }
-
-   rq->current_entity = entity;
-   reinit_completion(&entity->entity_idle);
-   spin_unlock(&rq->lock);
-   return entity;
-   }
+   if (drm_sched_entity_is_ready(entity))
+   goto found;
 
if (entity == rq->current_entity)
break;
@@ -308,6 +284,22 @@ drm_sched_rq_select_entity_rr(struct drm_gpu_scheduler 
*sched,
spin_unlock(&rq->lock);
 
return NULL;
+
+found:
+   if (!drm_sched_can_queue(sched, entity)) {
+   /*
+* If scheduler cannot take more jobs signal the caller to not
+* consider lower priority queues.
+*/
+   entity = ERR_PTR(-ENOSPC);
+   } else {
+   rq->current_entity = entity;
+   reinit_completion(&entity->entity_idle);
+   }
+
+   spin_unlock(&rq->lock);
+
+   return entity;
 }
 
 /**
-- 
2.48.0



[RFC v3 12/14] drm/sched: Embed run queue singleton into the scheduler

2025-03-31 Thread Tvrtko Ursulin
Now that the run queue to scheduler relationship is always 1:1 we can
embed it (the run queue) directly in the scheduler struct and save on
some allocation error handling code and such.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  |  6 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c |  6 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.h |  5 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h   |  8 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c |  8 ++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c |  8 ++---
 drivers/gpu/drm/scheduler/sched_entity.c| 34 +
 drivers/gpu/drm/scheduler/sched_fence.c |  2 +-
 drivers/gpu/drm/scheduler/sched_internal.h  |  6 ++--
 drivers/gpu/drm/scheduler/sched_main.c  | 31 +++
 drivers/gpu/drm/scheduler/sched_rq.c| 18 +--
 include/drm/gpu_scheduler.h |  5 +--
 12 files changed, 59 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 82df06a72ee0..e18e180bf32c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1108,7 +1108,8 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser 
*p)
if (p->gang_size > 1 && !adev->vm_manager.concurrent_flush) {
for (i = 0; i < p->gang_size; ++i) {
struct drm_sched_entity *entity = p->entities[i];
-   struct drm_gpu_scheduler *sched = entity->rq->sched;
+   struct drm_gpu_scheduler *sched =
+   container_of(entity->rq, typeof(*sched), rq);
struct amdgpu_ring *ring = to_amdgpu_ring(sched);
 
if (amdgpu_vmid_uses_reserved(vm, ring->vm_hub))
@@ -1236,7 +1237,8 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser 
*p)
return r;
}
 
-   sched = p->gang_leader->base.entity->rq->sched;
+   sched = container_of(p->gang_leader->base.entity->rq, typeof(*sched),
+rq);
while ((fence = amdgpu_sync_get_fence(&p->sync))) {
struct drm_sched_fence *s_fence = to_drm_sched_fence(fence);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 9440af58073b..e3d4f7503738 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -359,7 +359,9 @@ static struct dma_fence *
 amdgpu_job_prepare_job(struct drm_sched_job *sched_job,
  struct drm_sched_entity *s_entity)
 {
-   struct amdgpu_ring *ring = to_amdgpu_ring(s_entity->rq->sched);
+   struct drm_gpu_scheduler *sched =
+   container_of(s_entity->rq, typeof(*sched), rq);
+   struct amdgpu_ring *ring = to_amdgpu_ring(sched);
struct amdgpu_job *job = to_amdgpu_job(sched_job);
struct dma_fence *fence;
int r;
@@ -459,7 +461,7 @@ drm_sched_entity_queue_pop(struct drm_sched_entity *entity)
 
 void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)
 {
-   struct drm_sched_rq *rq = sched->rq;
+   struct drm_sched_rq *rq = &sched->rq;
struct drm_sched_entity *s_entity;
struct drm_sched_job *s_job;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
index ce6b9ba967ff..d6872baeba1e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
@@ -85,7 +85,10 @@ struct amdgpu_job {
 
 static inline struct amdgpu_ring *amdgpu_job_ring(struct amdgpu_job *job)
 {
-   return to_amdgpu_ring(job->base.entity->rq->sched);
+   struct drm_gpu_scheduler *sched =
+   container_of(job->base.entity->rq, typeof(*sched), rq);
+
+   return to_amdgpu_ring(sched);
 }
 
 int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
index 11dd2e0f7979..197d20a37afb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
@@ -145,6 +145,7 @@ TRACE_EVENT(amdgpu_cs,
 struct amdgpu_ib *ib),
TP_ARGS(p, job, ib),
TP_STRUCT__entry(
+__field(struct drm_gpu_scheduler *, sched)
 __field(struct amdgpu_bo_list *, bo_list)
 __field(u32, ring)
 __field(u32, dw)
@@ -152,11 +153,14 @@ TRACE_EVENT(amdgpu_cs,
 ),
 
TP_fast_assign(
+  __entry->sched = container_of(job->base.entity->rq,
+
typeof(*__entry->sched),
+   

[RFC v3 13/14] drm/sched: De-clutter drm_sched_init

2025-03-31 Thread Tvrtko Ursulin
Move work queue allocation into a helper for a more streamlined function
body.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
---
 drivers/gpu/drm/scheduler/sched_main.c | 28 +-
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index 4c52953a01a3..76eee43547a9 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -83,12 +83,6 @@
 #define CREATE_TRACE_POINTS
 #include "gpu_scheduler_trace.h"
 
-#ifdef CONFIG_LOCKDEP
-static struct lockdep_map drm_sched_lockdep_map = {
-   .name = "drm_sched_lockdep_map"
-};
-#endif
-
 static u32 drm_sched_available_credits(struct drm_gpu_scheduler *sched)
 {
u32 credits;
@@ -984,6 +978,19 @@ static void drm_sched_run_job_work(struct work_struct *w)
wake_up(&sched->job_scheduled);
 }
 
+static struct workqueue_struct *drm_sched_alloc_wq(const char *name)
+{
+#if (IS_ENABLED(CONFIG_LOCKDEP))
+   static struct lockdep_map map = {
+   .name = "drm_sched_lockdep_map"
+   };
+
+   return alloc_ordered_workqueue_lockdep_map(name, WQ_MEM_RECLAIM, &map);
+#else
+   return alloc_ordered_workqueue(name, WQ_MEM_RECLAIM);
+#endif
+}
+
 /**
  * drm_sched_init - Init a gpu scheduler instance
  *
@@ -1007,16 +1014,9 @@ int drm_sched_init(struct drm_gpu_scheduler *sched, 
const struct drm_sched_init_
sched->submit_wq = args->submit_wq;
sched->own_submit_wq = false;
} else {
-#ifdef CONFIG_LOCKDEP
-   sched->submit_wq = 
alloc_ordered_workqueue_lockdep_map(args->name,
-  
WQ_MEM_RECLAIM,
-  
&drm_sched_lockdep_map);
-#else
-   sched->submit_wq = alloc_ordered_workqueue(args->name, 
WQ_MEM_RECLAIM);
-#endif
+   sched->submit_wq = drm_sched_alloc_wq(args->name);
if (!sched->submit_wq)
return -ENOMEM;
-
sched->own_submit_wq = true;
}
 
-- 
2.48.0



Re: [PATCH v2] drm/panel: boe-bf060y8m-aj0: transition to mipi_dsi wrapped functions

2025-03-31 Thread Doug Anderson
Hi,

On Mon, Mar 31, 2025 at 1:28 PM Dmitry Baryshkov
 wrote:
>
> On Mon, Mar 31, 2025 at 08:06:36AM -0700, Doug Anderson wrote:
> > Hi,
> >
> > On Sun, Mar 30, 2025 at 11:18 PM Tejas Vipin  wrote:
> > >
> > > @@ -157,7 +137,6 @@ static int boe_bf060y8m_aj0_prepare(struct drm_panel 
> > > *panel)
> > >
> > > ret = boe_bf060y8m_aj0_on(boe);
> > > if (ret < 0) {
> > > -   dev_err(dev, "Failed to initialize panel: %d\n", ret);
> > > gpiod_set_value_cansleep(boe->reset_gpio, 1);
> > > return ret;
> >
> > It's not new, but the error handling here looks wrong to me. Instead
> > of just returning after setting the GPIO, this should be turning off
> > the regulators, shouldn't it? That would mean adding a new error label
> > for turning off "BF060Y8M_VREG_VCI" and then jumping to that.
>
> We should not be turning off the regulator in _prepare(), there will be
> an unmatched regulator disable call happening in _unprepare(). Of course
> it can be handled by adding a boolean, etc, but I think keeping them on
> is a saner thing.

Hr.

The issue is that if we're returning an error from a function the
caller should expect that the function undid anything that it did
partially. It _has_ to work that way, right? Otherwise we've lost the
context of exactly how far we got through the function so we don't
know which things to later undo and which things to later not undo.

...although I think you said that the DRM framework ignores errors
from prepare() and still calls unprepare(). I guess this is in
panel_bridge_atomic_pre_enable() where drm_panel_prepare()'s error
code is ignored? This feels like a bug waiting to happen. Are you
saying that boe_bf060y8m_aj0_unprepare() has to be written such that
it doesn't hit regulator underflows no matter which fail path
boe_bf060y8m_aj0_prepare() hit? That feels wrong.


-Doug


Re: [PATCH] drm/amd/display: replace use of msleep(<20) with usleep_range for better accuracy

2025-03-31 Thread James


On Mon, Mar 31, 2025, at 11:20 AM, Harry Wentland wrote:
> Agreed. Little timing changes often have unintended effects.
> I have no desire to change working code unless it's required
> to fix a real-life issue.
>
> Harry

Thanks for your explanation, and for taking the time to review.

Best regards,
James Flowers


Re: [PATCH v2 4/4] arm64: dts: rockchip: Enable HDMI1 on rock-5b

2025-03-31 Thread Sebastian Reichel
Hi,

On Mon, Mar 31, 2025 at 08:01:34PM +0100, Mark Brown wrote:
> On Wed, Dec 11, 2024 at 01:06:17AM +0200, Cristian Ciocaltea wrote:
> > Add the necessary DT changes to enable the second HDMI output port on
> > Radxa ROCK 5B.
> > 
> > While at it, switch the position of &vop_mmu and @vop to maintain the
> > alphabetical order.
> 
> We're seeing failures in the Arm lab the IGT tests on this board in
> Linus' tree which bisect to 77cea7ca1368 which is this patch.
> core_getversion fails:
>
>[...]
>
> The board is running fine in -next so hopefully there's a fix already
> there which will make it's way to Linus' tree during the merge window.
> We're also seeing something broken with the HDMI audio devices, but I
> didn't look into that.

I guess the root cause for the problem is, that the pull request for
the PHY subsystem [0] has not yet been merged. It contains [1]
("phy: phy-rockchip-samsung-hdptx: Don't use dt aliases to determine phy-id"),
a fix for properly handling the second RK3588 HDMI PHY instance.

[0] https://lore.kernel.org/all/Z+pFou7KOQZJ1iy4@vaman/
[1] 
https://web.git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git/commit/?h=next&id=f08d1c08563846f9be79a4859e912c8795d690fd

Greetings,

-- Sebastian


Re: [PATCH v3 1/2] arm64: dts: qcom: x1e78100-t14s: add hpd gpio to eDP panel

2025-03-31 Thread Christopher Obbard
Hi Dmitry,

On Mon, 31 Mar 2025 at 17:49, Dmitry Baryshkov
 wrote:
>
> On 31/03/2025 18:39, Christopher Obbard wrote:
> > Hi Johan,
> >
> > On Mon, 31 Mar 2025 at 09:50, Johan Hovold  wrote:
> >>
> >> On Thu, Mar 27, 2025 at 04:56:53PM +, Christopher Obbard wrote:
> >>> The eDP panel has an HPD GPIO. Describe it in the device tree
> >>> for the generic T14s model, as the HPD GPIO property is used in
> >>> both the OLED and LCD models which inherit this device tree.
> >>
> >> AFAICT, this patch is not correct as the hotplug detect signal is
> >> connected directly to the display controller on (these) Qualcomm SoCs
> >> and is already handled by its driver.
> >>
> >> Describing it as you do here leads to less accurate delays, see commits:
> >>
> >>  2327b13d6c47 ("drm/panel-edp: Take advantage of 
> >> wait_hpd_asserted() in struct drm_dp_aux").
> >>  3b5765df375c ("drm/panel: atna33xc20: Take advantage of 
> >> wait_hpd_asserted() in struct drm_dp_aux")
> >>
> >> Perhaps you lose some other functionality too.
> >>
> >>> Reviewed-by: Bryan O'Donoghue 
> >>> Signed-off-by: Christopher Obbard 
> >>> ---
> >>>   arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi | 11 
> >>> +++
> >>>   1 file changed, 11 insertions(+)
> >>>
> >>> diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi 
> >>> b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> >>> index 
> >>> 962fb050c55c4fd33f480a21a8c47a484d0c82b8..46c73f5c039ed982b553636cf8c4237a20ba7687
> >>>  100644
> >>> --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> >>> +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> >>> @@ -980,8 +980,12 @@ &mdss_dp3 {
> >>>aux-bus {
> >>>panel: panel {
> >>>compatible = "edp-panel";
> >>> + hpd-gpios = <&tlmm 119 GPIO_ACTIVE_HIGH>;
> >>>power-supply = <&vreg_edp_3p3>;
> >>>
> >>> + pinctrl-0 = <&edp_hpd_n_default>;
> >>> + pinctrl-names = "default";
> >>> +
> >>>port {
> >>>edp_panel_in: endpoint {
> >>>remote-endpoint = <&mdss_dp3_out>;
> >>> @@ -1286,6 +1290,13 @@ hall_int_n_default: hall-int-n-state {
> >>>bias-disable;
> >>>};
> >>>
> >>> + edp_hpd_n_default: edp-hpd-n-state {
> >>> + pins = "gpio119";
> >>> + function = "gpio";
> >>> + drive-strength = <2>;
> >>> + bias-pull-up;
> >>> + };
> >>
> >> I checked the firmware configuration for this pin on my T14s, which
> >> does not match what you have here. Instead the function is set to
> >> "edp0_hot" which forwards the signal to the display controller which
> >> already handles the signal on panel power on. (And there is also no
> >> internal pull up enabled).
> >>
> >> We may want to describe this pin configuration somewhere, but that's a
> >> separate issue.
> >
> > Thanks for your review, I will send another version in coming days and
> > drop this first patch (adding hpd to the T14s DTSI).
> >
> > As a consequence I will need to add no-hpd property to the panel node.
> No, you won't. There is a HPD line and it is routed to the DP controller.

OK, I think I misunderstand what Johan said. After taking some time to
think about it in more detail:
- The first commit will be changed so that the hpd GPIO will be added
to the X1E DP controller instead of the panel. grepping the source for
dp_hot_plug_det shows me how to do that. This part is clear.

- The panel node in the generic T14s DTSI should not have the
hpd-gpios property / pinctrl set.

- The panel node should not have the hpd-gpios property / pinctrl set.

I hope I understand that correctly. I will send a new series in the
morning unless there is any objection.

Thanks

Chris


Re: [PATCH v2] drm/panel: boe-bf060y8m-aj0: transition to mipi_dsi wrapped functions

2025-03-31 Thread Dmitry Baryshkov
On Mon, Mar 31, 2025 at 08:06:36AM -0700, Doug Anderson wrote:
> Hi,
> 
> On Sun, Mar 30, 2025 at 11:18 PM Tejas Vipin  wrote:
> >
> > @@ -157,7 +137,6 @@ static int boe_bf060y8m_aj0_prepare(struct drm_panel 
> > *panel)
> >
> > ret = boe_bf060y8m_aj0_on(boe);
> > if (ret < 0) {
> > -   dev_err(dev, "Failed to initialize panel: %d\n", ret);
> > gpiod_set_value_cansleep(boe->reset_gpio, 1);
> > return ret;
> 
> It's not new, but the error handling here looks wrong to me. Instead
> of just returning after setting the GPIO, this should be turning off
> the regulators, shouldn't it? That would mean adding a new error label
> for turning off "BF060Y8M_VREG_VCI" and then jumping to that.

We should not be turning off the regulator in _prepare(), there will be
an unmatched regulator disable call happening in _unprepare(). Of course
it can be handled by adding a boolean, etc, but I think keeping them on
is a saner thing.

> 
> Given that we're already squeezing an error handling fix into this
> patch, maybe it would make sense to add this one too (and, of course,
> mention it in the commit message).
> 
> -Doug

-- 
With best wishes
Dmitry


Re: [PATCH v2] drm/amdkfd: Change svm_range_get_info return type

2025-03-31 Thread Felix Kuehling

On 2025-03-31 09:18, Ваторопин Андрей wrote:

From: Andrey Vatoropin 

Static analysis shows that pointer "svms" cannot be NULL because it points
to the object "struct svm_range_list". Remove the extra NULL check. It is
meaningless and harms the readability of the code.

In the function svm_range_get_info() there is no possibility of failure.
Therefore, the caller of the function svm_range_get_info() does not need
a return value. Change the function svm_range_get_info() return type from
"int" to "void".

Since the function svm_range_get_info() has a return type of "void". The
caller of the function svm_range_get_info() does not need a return value.
Delete extra code.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Signed-off-by: Andrey Vatoropin 
---
v1 -> v2: also change return type of svm_range_get_info() per Felix Kuehling 
suggestion
Thank you for the patch. It seems you lost the change in 
kfd_criu_checkpoint_svm from the first version. Was that accidental or 
were you planning to send another patch?


I'm also having trouble applying your patches automatically with git am. 
Apparently you're using DOS CR-LF line endings, and --no-keep-cr isn't 
helping. I finally made it work with "git am --quoted-cr=strip ...". 
Please check your workflow for generating patches.


Thanks,
  Felix



  drivers/gpu/drm/amd/amdkfd/kfd_chardev.c |  4 +---
  drivers/gpu/drm/amd/amdkfd/kfd_svm.c |  7 ++-
  drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 11 +--
  3 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 1e9dd00620bf..a2149afa5803 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -2039,9 +2039,7 @@ static int criu_get_process_object_info(struct 
kfd_process *p,
  
  	num_events = kfd_get_num_events(p);
  
-	ret = svm_range_get_info(p, &num_svm_ranges, &svm_priv_data_size);

-   if (ret)
-   return ret;
+   svm_range_get_info(p, &num_svm_ranges, &svm_priv_data_size);
  
  	*num_objects = num_queues + num_events + num_svm_ranges;
  
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c

index 100717a98ec1..1b7d57a1b245 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -4076,8 +4076,8 @@ int kfd_criu_restore_svm(struct kfd_process *p,
return ret;
  }
  
-int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,

-  uint64_t *svm_priv_data_size)
+void svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
+   uint64_t *svm_priv_data_size)
  {
uint64_t total_size, accessibility_size, common_attr_size;
int nattr_common = 4, nattr_accessibility = 1;
@@ -4089,8 +4089,6 @@ int svm_range_get_info(struct kfd_process *p, uint32_t 
*num_svm_ranges,
*svm_priv_data_size = 0;
  
  	svms = &p->svms;

-   if (!svms)
-   return -EINVAL;
  
  	mutex_lock(&svms->lock);

list_for_each_entry(prange, &svms->list, list) {
@@ -4132,7 +4130,6 @@ int svm_range_get_info(struct kfd_process *p, uint32_t 
*num_svm_ranges,
  
  	pr_debug("num_svm_ranges %u total_priv_size %llu\n", *num_svm_ranges,

 *svm_priv_data_size);
-   return 0;
  }
  
  int kfd_criu_checkpoint_svm(struct kfd_process *p,

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
index 6ea23c78009c..01c7a4877904 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
@@ -184,8 +184,8 @@ void schedule_deferred_list_work(struct svm_range_list 
*svms);
  void svm_range_dma_unmap_dev(struct device *dev, dma_addr_t *dma_addr,
 unsigned long offset, unsigned long npages);
  void svm_range_dma_unmap(struct svm_range *prange);
-int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
-  uint64_t *svm_priv_data_size);
+void svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
+   uint64_t *svm_priv_data_size);
  int kfd_criu_checkpoint_svm(struct kfd_process *p,
uint8_t __user *user_priv_data,
uint64_t *priv_offset);
@@ -237,13 +237,12 @@ static inline int svm_range_schedule_evict_svm_bo(
return -EINVAL;
  }
  
-static inline int svm_range_get_info(struct kfd_process *p,

-uint32_t *num_svm_ranges,
-uint64_t *svm_priv_data_size)
+static inline void svm_range_get_info(struct kfd_process *p,
+ uint32_t *num_svm_ranges,
+ uint64_t *svm_priv_data_size)
  {
*num_svm_ranges = 0;
*svm_priv_data_size = 0;
-   return 0;
  }
  
  static inline int kfd_criu_checkpoint_svm(struct kfd_pr

Re: [PATCH RFC 00/12] dma: Enable dmem cgroup tracking

2025-03-31 Thread Dave Airlie
On Tue, 11 Mar 2025 at 00:26, Maxime Ripard  wrote:
>
> Hi,
>
> On Mon, Mar 10, 2025 at 03:16:53PM +0100, Christian König wrote:
> > [Adding Ben since we are currently in the middle of a discussion
> > regarding exactly that problem]
> >
> > Just for my understanding before I deep dive into the code: This uses
> > a separate dmem cgroup and does not account against memcg, don't it?
>
> Yes. The main rationale being that it doesn't always make sense to
> register against memcg: a lot of devices are going to allocate from
> dedicated chunks of memory that are either carved out from the main
> memory allocator, or not under Linux supervision at all.
>
> And if there's no way to make it consistent across drivers, it's not the
> right tool.
>

While I agree on that, if a user can cause a device driver to allocate
memory that is also memory that memcg accounts, then we have to
interface with memcg to account that memory.

The pathological case would be a single application wanting to use 90%
of RAM for device allocations, freeing it all, then using 90% of RAM
for normal usage. How to create a policy that would allow that with
dmem and memcg is difficult, since if you say you can do 90% on both
then the user can easily OOM the system.

Dave.
> Maxime


Re: [PATCH v2] backlight: pm8941: Add NULL check in wled_configure()

2025-03-31 Thread Dmitry Baryshkov
On Mon, Mar 31, 2025 at 10:16:54PM +0800, Henry Martin wrote:
> devm_kasprintf() return NULL if memory allocation fails. Currently,
> wled_configure() does not check for this case, leading to a possible NULL
> pointer dereference.
> 
> Add NULL check after devm_kasprintf() to prevent this issue.
> 
> Fixes: f86b77583d88 ("backlight: pm8941: Convert to using %pOFn instead of 
> device_node.name")
> Signed-off-by: Henry Martin 
> ---
> V1 -> V2: Fix commit message to use imperative mood and wrap lines to 75
> characters.
> 
>  drivers/video/backlight/qcom-wled.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov 

-- 
With best wishes
Dmitry


[RFC v3 01/14] drm/sched: Add some scheduling quality unit tests

2025-03-31 Thread Tvrtko Ursulin
Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
Cc: Pierre-Eric Pelloux-Prayer 
---
 drivers/gpu/drm/scheduler/tests/Makefile  |   3 +-
 .../gpu/drm/scheduler/tests/tests_scheduler.c | 548 ++
 2 files changed, 550 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/scheduler/tests/tests_scheduler.c

diff --git a/drivers/gpu/drm/scheduler/tests/Makefile 
b/drivers/gpu/drm/scheduler/tests/Makefile
index 5bf707bad373..9ec185fbbc15 100644
--- a/drivers/gpu/drm/scheduler/tests/Makefile
+++ b/drivers/gpu/drm/scheduler/tests/Makefile
@@ -2,6 +2,7 @@
 
 drm-sched-tests-y := \
 mock_scheduler.o \
-tests_basic.o
+tests_basic.o \
+tests_scheduler.o
 
 obj-$(CONFIG_DRM_SCHED_KUNIT_TEST) += drm-sched-tests.o
diff --git a/drivers/gpu/drm/scheduler/tests/tests_scheduler.c 
b/drivers/gpu/drm/scheduler/tests/tests_scheduler.c
new file mode 100644
index ..aa37c0dc8d66
--- /dev/null
+++ b/drivers/gpu/drm/scheduler/tests/tests_scheduler.c
@@ -0,0 +1,548 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025 Valve Corporation */
+
+#include 
+#include 
+#include 
+
+#include "sched_tests.h"
+
+/*
+ * DRM scheduler scheduler tests exercise load balancing decisions ie. entity
+ * selection logic.
+ */
+
+static int drm_sched_scheduler_init(struct kunit *test)
+{
+   struct drm_mock_scheduler *sched;
+
+   sched = drm_mock_sched_new(test, MAX_SCHEDULE_TIMEOUT);
+   sched->base.credit_limit = 1;
+
+   test->priv = sched;
+
+   return 0;
+}
+
+static void drm_sched_scheduler_exit(struct kunit *test)
+{
+   struct drm_mock_scheduler *sched = test->priv;
+
+   drm_mock_sched_fini(sched);
+}
+
+static void drm_sched_scheduler_queue_overhead(struct kunit *test)
+{
+   struct drm_mock_scheduler *sched = test->priv;
+   struct drm_mock_sched_entity *entity;
+   const unsigned int job_us = 1000;
+   const unsigned int jobs = 1000;
+   const unsigned int total_us = jobs * job_us;
+   struct drm_mock_sched_job *job, *first;
+   ktime_t start, end;
+   bool done;
+   int i;
+
+   /*
+* Deep queue job at a time processing (single credit).
+*
+* This measures the overhead of picking and processing a job at a time
+* by comparing the ideal total "GPU" time of all submitted jobs versus
+* the time actually taken.
+*/
+
+   KUNIT_ASSERT_EQ(test, sched->base.credit_limit, 1);
+
+   entity = drm_mock_sched_entity_new(test,
+  DRM_SCHED_PRIORITY_NORMAL,
+  sched);
+
+   for (i = 0; i <= jobs; i++) {
+   job = drm_mock_sched_job_new(test, entity);
+   if (i == 0)
+   first = job; /* Extra first job blocks the queue */
+   else
+   drm_mock_sched_job_set_duration_us(job, job_us);
+   drm_mock_sched_job_submit(job);
+   }
+
+   done = drm_mock_sched_job_wait_scheduled(first, HZ);
+   KUNIT_ASSERT_TRUE(test, done);
+
+   start = ktime_get();
+   i = drm_mock_sched_advance(sched, 1); /* Release the queue */
+   KUNIT_ASSERT_EQ(test, i, 1);
+
+   done = drm_mock_sched_job_wait_finished(job,
+   usecs_to_jiffies(total_us) * 5);
+   end = ktime_get();
+   KUNIT_ASSERT_TRUE(test, done);
+
+   pr_info("Expected %uus, actual %lldus\n",
+   total_us,
+   ktime_to_us(ktime_sub(end, start)));
+
+   drm_mock_sched_entity_free(entity);
+}
+
+static void drm_sched_scheduler_ping_pong(struct kunit *test)
+{
+   struct drm_mock_sched_job *job, *first, *prev = NULL;
+   struct drm_mock_scheduler *sched = test->priv;
+   struct drm_mock_sched_entity *entity[2];
+   const unsigned int job_us = 1000;
+   const unsigned int jobs = 1000;
+   const unsigned int total_us = jobs * job_us;
+   ktime_t start, end;
+   bool done;
+   int i;
+
+   /*
+* Two entitites in inter-dependency chain.
+*
+* This measures the overhead of picking and processing a job at a time,
+* where each job depends on the previous one from the diffferent
+* entity, by comparing the ideal total "GPU" time of all submitted jobs
+* versus the time actually taken.
+*/
+
+   KUNIT_ASSERT_EQ(test, sched->base.credit_limit, 1);
+
+   for (i = 0; i < ARRAY_SIZE(entity); i++)
+   entity[i] = drm_mock_sched_entity_new(test,
+ DRM_SCHED_PRIORITY_NORMAL,
+ sched);
+
+   for (i = 0; i <= jobs; i++) {
+   job = drm_mock_sched_job_new(test, entity[i & 1]);
+   if (i == 0)
+   first = job; /* Extra first jo

[RFC v3 08/14] drm/sched: Move run queue related code into a separate file

2025-03-31 Thread Tvrtko Ursulin
Lets move all the code dealing with struct drm_sched_rq into a separate
compilation unit. Advantage being sched_main.c is left with a clearer set
of responsibilities.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
---
 drivers/gpu/drm/scheduler/Makefile |   2 +-
 drivers/gpu/drm/scheduler/sched_internal.h |   7 +
 drivers/gpu/drm/scheduler/sched_main.c | 213 +---
 drivers/gpu/drm/scheduler/sched_rq.c   | 217 +
 4 files changed, 227 insertions(+), 212 deletions(-)
 create mode 100644 drivers/gpu/drm/scheduler/sched_rq.c

diff --git a/drivers/gpu/drm/scheduler/Makefile 
b/drivers/gpu/drm/scheduler/Makefile
index 6e13e4c63e9d..74e75eff6df5 100644
--- a/drivers/gpu/drm/scheduler/Makefile
+++ b/drivers/gpu/drm/scheduler/Makefile
@@ -20,7 +20,7 @@
 # OTHER DEALINGS IN THE SOFTWARE.
 #
 #
-gpu-sched-y := sched_main.o sched_fence.o sched_entity.o
+gpu-sched-y := sched_main.o sched_fence.o sched_entity.o sched_rq.o
 
 obj-$(CONFIG_DRM_SCHED) += gpu-sched.o
 
diff --git a/drivers/gpu/drm/scheduler/sched_internal.h 
b/drivers/gpu/drm/scheduler/sched_internal.h
index 8e7e477bace3..ee13a986b920 100644
--- a/drivers/gpu/drm/scheduler/sched_internal.h
+++ b/drivers/gpu/drm/scheduler/sched_internal.h
@@ -10,8 +10,15 @@ extern int drm_sched_policy;
 #define DRM_SCHED_POLICY_RR0
 #define DRM_SCHED_POLICY_FIFO  1
 
+bool drm_sched_can_queue(struct drm_gpu_scheduler *sched,
+struct drm_sched_entity *entity);
 void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
 
+void drm_sched_rq_init(struct drm_gpu_scheduler *sched,
+  struct drm_sched_rq *rq);
+struct drm_sched_entity *
+drm_sched_rq_select_entity(struct drm_gpu_scheduler *sched,
+  struct drm_sched_rq *rq);
 struct drm_gpu_scheduler *
 drm_sched_rq_add_entity(struct drm_sched_entity *entity, ktime_t ts);
 void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index 8736c7cd3ddd..f9c82db69300 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -117,8 +117,8 @@ static u32 drm_sched_available_credits(struct 
drm_gpu_scheduler *sched)
  * Return true if we can push at least one more job from @entity, false
  * otherwise.
  */
-static bool drm_sched_can_queue(struct drm_gpu_scheduler *sched,
-   struct drm_sched_entity *entity)
+bool drm_sched_can_queue(struct drm_gpu_scheduler *sched,
+struct drm_sched_entity *entity)
 {
struct drm_sched_job *s_job;
 
@@ -138,215 +138,6 @@ static bool drm_sched_can_queue(struct drm_gpu_scheduler 
*sched,
return drm_sched_available_credits(sched) >= s_job->credits;
 }
 
-static __always_inline bool drm_sched_entity_compare_before(struct rb_node *a,
-   const struct 
rb_node *b)
-{
-   struct drm_sched_entity *ent_a =  rb_entry((a), struct 
drm_sched_entity, rb_tree_node);
-   struct drm_sched_entity *ent_b =  rb_entry((b), struct 
drm_sched_entity, rb_tree_node);
-
-   return ktime_before(ent_a->oldest_job_waiting, 
ent_b->oldest_job_waiting);
-}
-
-static void drm_sched_rq_remove_fifo_locked(struct drm_sched_entity *entity,
-   struct drm_sched_rq *rq)
-{
-   lockdep_assert_held(&entity->lock);
-   lockdep_assert_held(&rq->lock);
-
-   if (!RB_EMPTY_NODE(&entity->rb_tree_node)) {
-   rb_erase_cached(&entity->rb_tree_node, &rq->rb_tree_root);
-   RB_CLEAR_NODE(&entity->rb_tree_node);
-   }
-}
-
-static void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity,
-   struct drm_sched_rq *rq,
-   ktime_t ts)
-{
-   /*
-* Both locks need to be grabbed, one to protect from entity->rq change
-* for entity from within concurrent drm_sched_entity_select_rq and the
-* other to update the rb tree structure.
-*/
-   lockdep_assert_held(&entity->lock);
-   lockdep_assert_held(&rq->lock);
-
-   drm_sched_rq_remove_fifo_locked(entity, rq);
-
-   entity->oldest_job_waiting = ts;
-
-   rb_add_cached(&entity->rb_tree_node, &rq->rb_tree_root,
- drm_sched_entity_compare_before);
-}
-
-/**
- * drm_sched_rq_init - initialize a given run queue struct
- *
- * @sched: scheduler instance to associate with this run queue
- * @rq: scheduler run queue
- *
- * Initializes a scheduler runqueue.
- */
-static void drm_sched_rq_init(struct drm_gpu_scheduler *sched,
- struct drm_sched_rq *rq)
-{
-   spin_lock_init(&rq->lock);
-   INIT_LIST_HEAD(&rq->entities);
-   rq->rb_tree_root = RB_ROOT_CACHED;
-   rq->sched = sched;
-}
-

[RFC v3 00/14] Deadline DRM scheduler

2025-03-31 Thread Tvrtko Ursulin
This is similar to v2 but I dropped some patches (for now) and added some new
ones. Most notably deadline scaling based on queue depth appears to be able to
add a little bit of fairness with spammy clients (deep submission queue).

As such, on the high level main advantages of the series:

 1. Code simplification - no more multiple run queues.
 2. Scheduling quality - schedules better than FIFO.
 3. No more RR is even more code simplification but this one needs to be tested
and approved by someone who actually uses RR.

In the future futher simplifactions and improvements should be possible on top
of this work. But for now I keep it simple.

First patch adds some unit tests which allow for easy evaluation of scheduling
behaviour against different client submission patterns. From there onwards it is
a hopefully natural progression of patches (or close) to the end result which is
a slightly more fair scheduler than FIFO.

Regarding the submission patterns tested, it is always two parallel clients
and they broadly cover these categories:

 * Deep queue clients
 * Hogs versus interactive
 * Priority handling

Lets look at the results:

1. Two normal priority deep queue clients.

These ones submit one second worth of 8ms jobs. As fast as they can, no
dependencies etc. There is no difference in runtime between FIFO and qddl but
the latter allows both clients to progress with work more evenly:

https://people.igalia.com/tursulin/drm-sched-qddl/normal-normal.png

(X axis is time, Y is submitted queue-depth, hence lowering of qd corresponds
  with work progress for both clients, tested with both schedulers separately.)

2. Same two clients but one is now low priority.

https://people.igalia.com/tursulin/drm-sched-qddl/normal-low.png

Normal priority client is a solid line, low priority dotted. We can see how FIFO
completely starves the low priority client until the normal priority is fully
done. Only then the low priority client gets any GPU time.

In constrast, qddl allows some GPU time to the low priority client.

3. Same clients but now high versus normal priority.

Similar behaviour as in the previous one with normal a bit less de-prioritised
relative to high, than low was against normal.

https://people.igalia.com/tursulin/drm-sched-qddl/high-normal.png

4. Heavy load vs interactive client.

Heavy client emits a 75% GPU load in the format of 3x 2.5ms jobs followed by a
2.5ms wait.

Interactive client emites a 10% GPU load in the format of 1x 1ms job followed
by a 9ms wait.

This simulates an interactive graphical client used on top of a relatively heavy
background load but no GPU oversubscription.

Graphs show the interactive client only and from now on, instead of looking at
the client's queue depth, we look at its "fps".

https://people.igalia.com/tursulin/drm-sched-qddl/heavy-interactive.png

We can see that qddl allows a slighty higher fps for the interactive client
which is good.

5. Low priority GPU hog versus heavy-interactive.

Low priority client: 3x 2.5ms jobs client followed by a 0.5ms wait.
Interactive client: 1x 0.5ms job followed by a 10ms wait.

https://people.igalia.com/tursulin/drm-sched-qddl/lowhog-interactive.png

No difference between the schedulers.

6. Last set of test scenarios will have three subgroups.

In all cases we have two interactive (synchronous, single job at a time) clients
with a 50% "duty cycle" GPU time usage.

Client 1: 1.5ms job + 1.5ms wait (aka short bursty)
Client 2: 2.5ms job + 2.5ms wait (aka long bursty)

a) Both normal priority.

https://people.igalia.com/tursulin/drm-sched-qddl/5050-short.png
https://people.igalia.com/tursulin/drm-sched-qddl/5050-long.png

Both schedulers favour the higher frequency duty cycle with qddl giving it a
little bit more which should be good for interactivity.

b) Normal vs low priority.

https://people.igalia.com/tursulin/drm-sched-qddl/5050-normal-low-normal.png
https://people.igalia.com/tursulin/drm-sched-qddl/5050-normal-low-low.png

Qddl gives a bit more to the normal than low.

c) High vs normal priority.

https://people.igalia.com/tursulin/drm-sched-qddl/5050-high-normal-high.png
https://people.igalia.com/tursulin/drm-sched-qddl/5050-high-normal-normal.png

Again, qddl gives a bit more share to the higher priority client.

On the overall qddl looks like a potential improvement in terms of fairness,
especially avoiding priority starvation. There do not appear to be any
regressions with the tested workloads.

As before, I am looking for feedback, ideas for what kind of submission
scenarios to test. Testers on different GPUs would be very welcome too.

And I should probably test round-robin at some point, to see if we are maybe
okay to drop unconditionally, it or further work improving qddl would be needed.

v2:
 * Fixed many rebase errors.
 * Added some new patches.
 * Dropped single shot dependecy handling.

v3:
 * Added scheduling quality unit tests.
 * Refined a tiny bit by adding some fairness.
 * Dropped a few patches for n

[PATCH v3] backlight: pm8941: Add NULL check in wled_configure()

2025-03-31 Thread Henry Martin
devm_kasprintf() returns NULL when memory allocation fails. Currently,
wled_configure() does not check for this case, which results in a NULL
pointer dereference.

Add NULL check after devm_kasprintf() to prevent this issue.

Fixes: f86b77583d88 ("backlight: pm8941: Convert to using %pOFn instead of 
device_node.name")
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Henry Martin 
---
V2 -> V3: Correct commit meessage and confirm this patch has considered
resource cleanup to avoid any subsequent issues, ensuring that errors
are handled properly and no resources are left in an inconsistent
state.
V1 -> V2: Fix commit message to use imperative mood and wrap lines to 75
characters.

 drivers/video/backlight/qcom-wled.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/video/backlight/qcom-wled.c 
b/drivers/video/backlight/qcom-wled.c
index 9afe701b2a1b..a63bb42c8f8b 100644
--- a/drivers/video/backlight/qcom-wled.c
+++ b/drivers/video/backlight/qcom-wled.c
@@ -1406,9 +1406,11 @@ static int wled_configure(struct wled *wled)
wled->ctrl_addr = be32_to_cpu(*prop_addr);
 
rc = of_property_read_string(dev->of_node, "label", &wled->name);
-   if (rc)
+   if (rc) {
wled->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn", 
dev->of_node);
-
+   if (!wled->name)
+   return -ENOMEM;
+   }
switch (wled->version) {
case 3:
u32_opts = wled3_opts;
-- 
2.34.1



Re: [PATCH v2 2/2] drm/msm/dp: Introduce link training per-segment for LTTPRs

2025-03-31 Thread Dmitry Baryshkov
On Wed, Mar 12, 2025 at 12:38:04AM +0100, Aleksandrs Vinarskis wrote:
> DisplayPort requires per-segment link training when LTTPR are switched
> to non-transparent mode, starting with LTTPR closest to the source.
> Only when each segment is trained individually, source can link train
> to sink.
> 
> Implement per-segment link traning when LTTPR(s) are detected, to
> support external docking stations. On higher level, changes are:
> 
> * Pass phy being trained down to all required helpers
> * Run CR, EQ link training per phy
> * Set voltage swing, pre-emphasis levels per phy
> 
> This ensures successful link training both when connected directly to
> the monitor (single LTTPR onboard most X1E laptops) and via the docking
> station (at least two LTTPRs).
> 
> Signed-off-by: Aleksandrs Vinarskis 
> Reviewed-by: Abel Vesa 
> ---
>  drivers/gpu/drm/msm/dp/dp_ctrl.c| 137 +++-
>  drivers/gpu/drm/msm/dp/dp_ctrl.h|   2 +-
>  drivers/gpu/drm/msm/dp/dp_display.c |   4 +-
>  3 files changed, 99 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c 
> b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> index d8633a596f8d..419a519ccf6b 100644
> --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
> +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> @@ -79,6 +79,8 @@ struct msm_dp_ctrl_private {
>   struct msm_dp_link *link;
>   struct msm_dp_catalog *catalog;
>  
> + int *lttpr_count;

Please move lttpr_count to msm_dp_ctrl or msm_dp_link. It would remove a
need for this ugly pointer.

> +
>   struct phy *phy;
>  
>   unsigned int num_core_clks;
> @@ -1034,9 +1036,11 @@ static int msm_dp_ctrl_set_vx_px(struct 
> msm_dp_ctrl_private *ctrl,
>   return 0;
>  }
>  
> -static int msm_dp_ctrl_update_vx_px(struct msm_dp_ctrl_private *ctrl)
> +static int msm_dp_ctrl_update_phy_vx_px(struct msm_dp_ctrl_private *ctrl,
> + enum drm_dp_phy dp_phy)
>  {
>   struct msm_dp_link *link = ctrl->link;
> + int reg = DP_TRAINING_LANE0_SET;
>   int ret = 0, lane, lane_cnt;
>   u8 buf[4];
>   u32 max_level_reached = 0;
> @@ -1075,8 +1079,11 @@ static int msm_dp_ctrl_update_vx_px(struct 
> msm_dp_ctrl_private *ctrl)
>  
>   drm_dbg_dp(ctrl->drm_dev, "sink: p|v=0x%x\n",
>   voltage_swing_level | pre_emphasis_level);
> - ret = drm_dp_dpcd_write(ctrl->aux, DP_TRAINING_LANE0_SET,
> - buf, lane_cnt);
> +
> + if (dp_phy != DP_PHY_DPRX)
> + reg = DP_TRAINING_LANE0_SET_PHY_REPEATER(dp_phy);

Please always init reg here rather than using a default value above.
It's a cleaner code IMO.

> +
> + ret = drm_dp_dpcd_write(ctrl->aux, reg, buf, lane_cnt);
>   if (ret == lane_cnt)
>   ret = 0;
>  
> @@ -1084,9 +1091,10 @@ static int msm_dp_ctrl_update_vx_px(struct 
> msm_dp_ctrl_private *ctrl)
>  }
>  
>  static bool msm_dp_ctrl_train_pattern_set(struct msm_dp_ctrl_private *ctrl,
> - u8 pattern)
> + u8 pattern, enum drm_dp_phy dp_phy)
>  {
>   u8 buf;
> + int reg = DP_TRAINING_PATTERN_SET;
>   int ret = 0;
>  
>   drm_dbg_dp(ctrl->drm_dev, "sink: pattern=%x\n", pattern);
> @@ -1096,7 +1104,10 @@ static bool msm_dp_ctrl_train_pattern_set(struct 
> msm_dp_ctrl_private *ctrl,
>   if (pattern && pattern != DP_TRAINING_PATTERN_4)
>   buf |= DP_LINK_SCRAMBLING_DISABLE;
>  
> - ret = drm_dp_dpcd_writeb(ctrl->aux, DP_TRAINING_PATTERN_SET, buf);
> + if (dp_phy != DP_PHY_DPRX)
> + reg = DP_TRAINING_PATTERN_SET_PHY_REPEATER(dp_phy);

The same comment here.

> +
> + ret = drm_dp_dpcd_writeb(ctrl->aux, reg, buf);
>   return ret == 1;
>  }
>  
> @@ -1115,12 +1126,16 @@ static int msm_dp_ctrl_read_link_status(struct 
> msm_dp_ctrl_private *ctrl,
>  }
>  
>  static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
> - int *training_step)
> + int *training_step, enum drm_dp_phy dp_phy)
>  {
> + int delay_us;
>   int tries, old_v_level, ret = 0;
>   u8 link_status[DP_LINK_STATUS_SIZE];
>   int const maximum_retries = 4;
>  
> + delay_us = drm_dp_read_clock_recovery_delay(ctrl->aux,
> + ctrl->panel->dpcd, dp_phy, false);
> +
>   msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
>  
>   *training_step = DP_TRAINING_1;
> @@ -1129,18 +1144,19 @@ static int msm_dp_ctrl_link_train_1(struct 
> msm_dp_ctrl_private *ctrl,
>   if (ret)
>   return ret;
>   msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 |
> - DP_LINK_SCRAMBLING_DISABLE);
> + DP_LINK_SCRAMBLING_DISABLE, dp_phy);
>  
> - ret = msm_dp_ctrl_update_vx_px(ctrl);
> + msm_dp_link_reset_phy_params_vx_px(ctrl->link);
> + ret = msm_dp_ctrl_update_phy_vx_px(ctrl, dp_phy);
>   if (ret)
>   return ret;
>  
>   tries = 0;
>   old_v_level = ctrl->link->phy_params.v_level;
> 

Re: [PATCH v2] drm/panel: boe-bf060y8m-aj0: transition to mipi_dsi wrapped functions

2025-03-31 Thread Dmitry Baryshkov
On Mon, Mar 31, 2025 at 03:40:27PM -0700, Doug Anderson wrote:
> Hi,
> 
> On Mon, Mar 31, 2025 at 1:28 PM Dmitry Baryshkov
>  wrote:
> >
> > On Mon, Mar 31, 2025 at 08:06:36AM -0700, Doug Anderson wrote:
> > > Hi,
> > >
> > > On Sun, Mar 30, 2025 at 11:18 PM Tejas Vipin  
> > > wrote:
> > > >
> > > > @@ -157,7 +137,6 @@ static int boe_bf060y8m_aj0_prepare(struct 
> > > > drm_panel *panel)
> > > >
> > > > ret = boe_bf060y8m_aj0_on(boe);
> > > > if (ret < 0) {
> > > > -   dev_err(dev, "Failed to initialize panel: %d\n", ret);
> > > > gpiod_set_value_cansleep(boe->reset_gpio, 1);
> > > > return ret;
> > >
> > > It's not new, but the error handling here looks wrong to me. Instead
> > > of just returning after setting the GPIO, this should be turning off
> > > the regulators, shouldn't it? That would mean adding a new error label
> > > for turning off "BF060Y8M_VREG_VCI" and then jumping to that.
> >
> > We should not be turning off the regulator in _prepare(), there will be
> > an unmatched regulator disable call happening in _unprepare(). Of course
> > it can be handled by adding a boolean, etc, but I think keeping them on
> > is a saner thing.
> 
> Hr.
> 
> The issue is that if we're returning an error from a function the
> caller should expect that the function undid anything that it did
> partially. It _has_ to work that way, right? Otherwise we've lost the
> context of exactly how far we got through the function so we don't
> know which things to later undo and which things to later not undo.

Kind of yes. I'd rather make drm_panel functions return void here, as
that matches panel bridge behaviour. The only driver that actually uses
return values of those functions is analogix_dp, see
analogix_dp_prepare_panel(). However most of invocations of that
function can go away. I'll send a patchset.

> 
> ...although I think you said that the DRM framework ignores errors
> from prepare() and still calls unprepare(). I guess this is in
> panel_bridge_atomic_pre_enable() where drm_panel_prepare()'s error
> code is ignored?

Yes.

> This feels like a bug waiting to happen. Are you
> saying that boe_bf060y8m_aj0_unprepare() has to be written such that
> it doesn't hit regulator underflows no matter which fail path
> boe_bf060y8m_aj0_prepare() hit? That feels wrong.

Let me try to fix that.

-- 
With best wishes
Dmitry


[PATCH v5] drm/syncobj: Extend EXPORT_SYNC_FILE for timeline syncobjs

2025-03-31 Thread Rob Clark
From: Rob Clark 

Add support for exporting a dma_fence fd for a specific point on a
timeline.  This is needed for vtest/vpipe[1][2] to implement timeline
syncobj support, as it needs a way to turn a point on a timeline back
into a dma_fence fd.  It also closes an odd omission from the syncobj
UAPI.

[1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33433
[2] https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/805

v2: Add DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_TIMELINE
v3: Add unstaged uabi header hunk
v4: Also handle IMPORT_SYNC_FILE case
v5: Address comments from Dmitry

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/drm_syncobj.c | 45 +++
 include/uapi/drm/drm.h|  4 
 2 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 4f2ab8a7b50f..b0a4c58fe726 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -741,7 +741,7 @@ static int drm_syncobj_fd_to_handle(struct drm_file 
*file_private,
 }
 
 static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private,
- int fd, int handle)
+ int fd, int handle, u64 point)
 {
struct dma_fence *fence = sync_file_get_fence(fd);
struct drm_syncobj *syncobj;
@@ -755,14 +755,22 @@ static int drm_syncobj_import_sync_file_fence(struct 
drm_file *file_private,
return -ENOENT;
}
 
-   drm_syncobj_replace_fence(syncobj, fence);
+   if (point) {
+   struct dma_fence_chain *chain = dma_fence_chain_alloc();
+   if (!chain)
+   return -ENOMEM;
+   drm_syncobj_add_point(syncobj, chain, fence, point);
+   } else {
+   drm_syncobj_replace_fence(syncobj, fence);
+   }
+
dma_fence_put(fence);
drm_syncobj_put(syncobj);
return 0;
 }
 
 static int drm_syncobj_export_sync_file(struct drm_file *file_private,
-   int handle, int *p_fd)
+   int handle, u64 point, int *p_fd)
 {
int ret;
struct dma_fence *fence;
@@ -772,7 +780,7 @@ static int drm_syncobj_export_sync_file(struct drm_file 
*file_private,
if (fd < 0)
return fd;
 
-   ret = drm_syncobj_find_fence(file_private, handle, 0, 0, &fence);
+   ret = drm_syncobj_find_fence(file_private, handle, point, 0, &fence);
if (ret)
goto err_put_fd;
 
@@ -869,6 +877,9 @@ drm_syncobj_handle_to_fd_ioctl(struct drm_device *dev, void 
*data,
   struct drm_file *file_private)
 {
struct drm_syncobj_handle *args = data;
+   unsigned valid_flags = DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_TIMELINE |
+  DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE;
+   u64 point = 0;
 
if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
return -EOPNOTSUPP;
@@ -876,13 +887,18 @@ drm_syncobj_handle_to_fd_ioctl(struct drm_device *dev, 
void *data,
if (args->pad)
return -EINVAL;
 
-   if (args->flags != 0 &&
-   args->flags != DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE)
+   if (args->flags & ~valid_flags)
return -EINVAL;
 
+   if (args->flags & DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_TIMELINE)
+   point = args->point;
+
if (args->flags & DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE)
return drm_syncobj_export_sync_file(file_private, args->handle,
-   &args->fd);
+   point, &args->fd);
+
+   if (args->point)
+   return -EINVAL;
 
return drm_syncobj_handle_to_fd(file_private, args->handle,
&args->fd);
@@ -893,6 +909,9 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void 
*data,
   struct drm_file *file_private)
 {
struct drm_syncobj_handle *args = data;
+   unsigned valid_flags = DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE |
+  DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE;
+   u64 point = 0;
 
if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
return -EOPNOTSUPP;
@@ -900,14 +919,20 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, 
void *data,
if (args->pad)
return -EINVAL;
 
-   if (args->flags != 0 &&
-   args->flags != DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE)
+   if (args->flags & ~valid_flags)
return -EINVAL;
 
+   if (args->flags & DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE)
+   point = args->point;
+
if (args->flags & DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE)
return d

[RFC v3 09/14] drm/sched: Add deadline policy

2025-03-31 Thread Tvrtko Ursulin
Deadline scheduling policy should be a fairer flavour of FIFO with two
main advantages being that it can naturally connect with the dma-fence
deadlines, and secondly that it can get away with multiple run queues per
scheduler.

>From the latter comes the fairness advantage. Where the current FIFO
policy will always starve low priority entities by normal, and normal
by high etc, deadline tracks all runnable entities in a single run queue
and assigns them deadlines based on priority. Instead of being ordered
strictly by priority, jobs and entities become ordered by deadlines.

This means that a later higher priority submission can still overtake an
earlier lower priority one, but eventually the lower priority will get its
turn even if high priority is constantly feeding new work.

Current mapping of priority to deadlines is somewhat arbitrary and looks
like this (submit timestamp plus constant offset in micro-seconds):

static const unsigned int d_us[] = {
[DRM_SCHED_PRIORITY_KERNEL] =100,
[DRM_SCHED_PRIORITY_HIGH]   =   1000,
[DRM_SCHED_PRIORITY_NORMAL] =   5000,
[DRM_SCHED_PRIORITY_LOW]= 10,
};

Assuming simultaneous submission of one normal and one low prioriy job at
a time of "t", they will get respective deadlines of t+5ms and t+100ms.
Hence normal will run first and low will run after it, or at the latest
100ms after it was submitted in case other higher priority submissions
overtake it in the meantime.

Because deadline policy does not need run queues, if the FIFO and RR
polices are later removed, that would allow for a significant
simplification of the code base by reducing the 1:N to 1:1 scheduler
to run queue relationship.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
---
 drivers/gpu/drm/scheduler/sched_entity.c   | 53 ++
 drivers/gpu/drm/scheduler/sched_internal.h |  9 +++-
 drivers/gpu/drm/scheduler/sched_main.c | 14 --
 drivers/gpu/drm/scheduler/sched_rq.c   |  4 +-
 include/drm/gpu_scheduler.h|  3 ++
 5 files changed, 65 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_entity.c 
b/drivers/gpu/drm/scheduler/sched_entity.c
index 8362184fe431..f4930b44f50d 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -70,6 +70,8 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
entity->guilty = guilty;
entity->num_sched_list = num_sched_list;
entity->priority = priority;
+   entity->rq_priority = drm_sched_policy == DRM_SCHED_POLICY_DEADLINE ?
+ DRM_SCHED_PRIORITY_KERNEL : priority;
/*
 * It's perfectly valid to initialize an entity without having a valid
 * scheduler attached. It's just not valid to use the scheduler before 
it
@@ -86,17 +88,23 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
 */
pr_warn("%s: called with uninitialized scheduler\n", __func__);
} else if (num_sched_list) {
-   /* The "priority" of an entity cannot exceed the number of 
run-queues of a
-* scheduler. Protect against num_rqs being 0, by converting to 
signed. Choose
-* the lowest priority available.
+   enum drm_sched_priority p = entity->priority;
+
+   /*
+* The "priority" of an entity cannot exceed the number of
+* run-queues of a scheduler. Protect against num_rqs being 0,
+* by converting to signed. Choose the lowest priority
+* available.
 */
-   if (entity->priority >= sched_list[0]->num_rqs) {
-   dev_err(sched_list[0]->dev, "entity has out-of-bounds 
priority: %u. num_rqs: %u\n",
-   entity->priority, sched_list[0]->num_rqs);
-   entity->priority = max_t(s32, (s32) 
sched_list[0]->num_rqs - 1,
-(s32) 
DRM_SCHED_PRIORITY_KERNEL);
+   if (p >= sched_list[0]->num_user_rqs) {
+   dev_err(sched_list[0]->dev, "entity with out-of-bounds 
priority:%u num_user_rqs:%u\n",
+   p, sched_list[0]->num_user_rqs);
+   p = max_t(s32,
+(s32)sched_list[0]->num_user_rqs - 1,
+(s32)DRM_SCHED_PRIORITY_KERNEL);
+   entity->priority = p;
}
-   entity->rq = sched_list[0]->sched_rq[entity->priority];
+   entity->rq = sched_list[0]->sched_rq[entity->rq_priority];
}
 
init_completion(&entity->entity_idle);
@@ -398,6 +406,27 @@ void drm_sched_entity_set_priority(struct drm_sched_entity 
*entity,
 }
 EXPORT_SYMBOL(drm_sched_entity_set_

[PATCH v2 1/2] drm/edid: Use unsigned int in drm_add_modes_noedid()

2025-03-31 Thread Lyude Paul
A negative resolution doesn't really make any sense, so let's make these
parameters unsigned. In C this doesn't make much of a difference, but Rust
is stricter about signed/unsigned casts and additionally can check for
arithmetic over/underflows if CONFIG_RUST_OVERFLOW_CHECKS is enabled.

Signed-off-by: Lyude Paul 
Cc: Greg Kroah-Hartman 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 

---

V2:
* Remove h/vdisplay < 0 checks in drm_add_modes_noedid()

Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/drm_edid.c | 10 ++
 include/drm/drm_edid.h |  2 +-
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 13bc4c290b17d..1e69326283dce 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -7099,18 +7099,12 @@ EXPORT_SYMBOL(drm_add_edid_modes);
  * Return: The number of modes added or 0 if we couldn't find any.
  */
 int drm_add_modes_noedid(struct drm_connector *connector,
-   int hdisplay, int vdisplay)
+unsigned int hdisplay, unsigned int vdisplay)
 {
-   int i, count, num_modes = 0;
+   int i, count = ARRAY_SIZE(drm_dmt_modes), num_modes = 0;
struct drm_display_mode *mode;
struct drm_device *dev = connector->dev;
 
-   count = ARRAY_SIZE(drm_dmt_modes);
-   if (hdisplay < 0)
-   hdisplay = 0;
-   if (vdisplay < 0)
-   vdisplay = 0;
-
for (i = 0; i < count; i++) {
const struct drm_display_mode *ptr = &drm_dmt_modes[i];
 
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index eaac5e665892a..b38409670868d 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -437,7 +437,7 @@ bool drm_detect_monitor_audio(const struct edid *edid);
 enum hdmi_quantization_range
 drm_default_rgb_quant_range(const struct drm_display_mode *mode);
 int drm_add_modes_noedid(struct drm_connector *connector,
-int hdisplay, int vdisplay);
+unsigned int hdisplay, unsigned int vdisplay);
 
 int drm_edid_header_is_valid(const void *edid);
 bool drm_edid_is_valid(struct edid *edid);
-- 
2.48.1



[PATCH v2 2/2] drm/mode_config: Make drm_mode_config.(max|min)_(width|height) unsigned

2025-03-31 Thread Lyude Paul
It doesn't make much sense to allow devices to specify their min/max
resolution as signed integers, and in Rust with CONFIG_RUST_OVERFLOW_CHECKS
enabled this provides us actual over/underflow checks. Similarly, it
doesn't really make much sense for us to allow devices to specify their
minimum/maximum resolution as signed.

Signed-off-by: Lyude Paul 
Reviewed-by: Maxime Ripard 
Cc: Greg Kroah-Hartman 
Cc: Thomas Zimmermann 

---

V2:
* No functional changes, just update the commit message w/r/t Thomas's
  comments.

Signed-off-by: Lyude Paul 
---
 include/drm/drm_mode_config.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 271765e2e9f2d..4b8f0370b79bf 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -532,8 +532,8 @@ struct drm_mode_config {
 */
struct list_head privobj_list;
 
-   int min_width, min_height;
-   int max_width, max_height;
+   unsigned int min_width, min_height;
+   unsigned int max_width, max_height;
const struct drm_mode_config_funcs *funcs;
 
/* output poll support */
-- 
2.48.1



[PATCH v2 0/2] drm: Make some resolution info unsigned

2025-03-31 Thread Lyude Paul
During the review of some of my patches for KMS bindings in Rust, it was
pointed out we have some areas of DRM that are storing resolutions as
signed integers when it doesn't really make sense. Since Rust has
arithematic overflow checking by default in the kernel, let's change
these to unsigned so that we can take advantage of that.

Lyude Paul (2):
  drm/edid: Use unsigned int in drm_add_modes_noedid()
  drm/mode_config: Make drm_mode_config.(max|min)_(width|height)
unsigned

 drivers/gpu/drm/drm_edid.c| 10 ++
 include/drm/drm_edid.h|  2 +-
 include/drm/drm_mode_config.h |  4 ++--
 3 files changed, 5 insertions(+), 11 deletions(-)


base-commit: cf05922d63e2ae6a9b1b52ff5236a44c3b29f78c
-- 
2.48.1



Re: [PATCH V8 11/43] drm/colorop: Introduce DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE

2025-03-31 Thread Shengyu Qu



在 2025/3/27 7:46, Alex Hung 写道:

From: Harry Wentland 

With the introduction of the pre-blending color pipeline we
can no longer have color operations that don't have a clear
position in the color pipeline. We deprecate all existing
plane properties. For upstream drivers those are:
  - COLOR_ENCODING
  - COLOR_RANGE

Drivers are expected to ignore these properties when
programming the HW. DRM clients that don't register with

don't?
Seems conflict with change note below.


DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE will not be allowed to
set the COLOR_ENCODING and COLOR_RANGE properties.

Setting of the COLOR_PIPELINE plane property or drm_colorop
properties is only allowed for userspace that sets this
client cap.

Signed-off-by: Alex Hung 
Signed-off-by: Harry Wentland 
---
v8:
  - Disallow setting of COLOR_RANGE and COLOR_ENCODING when
DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE is set

v5:
  - Fix kernel docs

v4:
  - Don't block setting of COLOR_RANGE and COLOR_ENCODING
when client cap is set


  drivers/gpu/drm/drm_atomic_uapi.c | 23 ++-
  drivers/gpu/drm/drm_ioctl.c   |  7 +++
  include/drm/drm_file.h|  7 +++
  include/uapi/drm/drm.h| 15 +++
  4 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 5738b1c18755..e0b4b122ef6b 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -567,10 +567,26 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
} else if (property == plane->zpos_property) {
state->zpos = val;
} else if (property == plane->color_encoding_property) {
+   if (file_priv->plane_color_pipeline) {
+   drm_dbg_atomic(dev,
+  "Setting COLOR_ENCODING plane property not 
permitted with DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE client cap\n");
+   return -EINVAL;
+   }
state->color_encoding = val;
} else if (property == plane->color_range_property) {
+   if (file_priv->plane_color_pipeline) {
+   drm_dbg_atomic(dev,
+  "Setting COLOR_RANGE plane property not 
permitted with DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE client cap\n");
+   return -EINVAL;
+   }
state->color_range = val;
} else if (property == plane->color_pipeline_property) {
+   if (!file_priv->plane_color_pipeline) {
+   drm_dbg_atomic(dev,
+  "Setting COLOR_PIPELINE plane property not 
permitted unless DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE is set\n");
+   return -EINVAL;
+   }
+
/* find DRM colorop object */
struct drm_colorop *colorop = NULL;
  
@@ -1197,6 +1213,12 @@ int drm_atomic_set_property(struct drm_atomic_state *state,

break;
}
case DRM_MODE_OBJECT_COLOROP: {
+   if (!file_priv->plane_color_pipeline) {
+   drm_dbg_atomic(prop->dev,
+  "[OBJECT:%d] is a colorop but 
DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE not set\n",
+  obj->id);
+   ret = -EINVAL;
+   }
struct drm_colorop *colorop = obj_to_colorop(obj);
struct drm_colorop_state *colorop_state;
  
@@ -1209,7 +1231,6 @@ int drm_atomic_set_property(struct drm_atomic_state *state,

ret = drm_atomic_colorop_set_property(colorop,
colorop_state, file_priv,
prop, prop_value);
-
break;
}
default:
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index f593dc569d31..5c89c586da7c 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -373,6 +373,13 @@ drm_setclientcap(struct drm_device *dev, void *data, 
struct drm_file *file_priv)
return -EINVAL;
file_priv->supports_virtualized_cursor_plane = req->value;
break;
+   case DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE:
+   if (!file_priv->atomic)
+   return -EINVAL;
+   if (req->value > 1)
+   return -EINVAL;
+   file_priv->plane_color_pipeline = req->value;
+   break;
default:
return -EINVAL;
}
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
index 94d365b22505..86929ca667aa 100644
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -206,6 +206,13 @@ struct drm_file {
 */
bool writeback_connectors;
  
+	/**

+* @plane_color_pipeline:
+*
+* True if client understands plane

Re: [RFC PATCH v2 5/6] drm/shmem: Add a helper to check object's page backing status

2025-03-31 Thread Thomas Zimmermann

Hi

Am 26.03.25 um 03:14 schrieb Adrián Larumbe:

Provide a helper function that lets shmem API users know whether a given
object is backed by physical pages, or else in the case of a sparse
shmem object, at least one of them is populated.

The obvious user is fdinfo, which needs to know an object's resident
status.

Signed-off-by: Adrián Larumbe 
---
  drivers/gpu/drm/drm_gem_shmem_helper.c | 18 ++
  include/drm/drm_gem_shmem_helper.h |  2 ++
  2 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 1bf33e5a1c4c..79ac7c7c953f 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -1033,6 +1033,24 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device 
*dev,
  }
  EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
  
+/**

+ * drm_gem_shmem_is_populated - Tell whether the shem object is backed by
+ * at least one page of physical memory
+ * @shmem: shmem GEM object
+ *
+ * Returns:
+ * A boolean, where the 'true' value depends on at least one page being preset
+ * in a sparse object's xarray, or all the shmem file pages for PRIME buffers
+ * and regular shmem objects.
+ */
+bool drm_gem_shmem_is_populated(struct drm_gem_shmem_object *shmem)
+{
+   return (shmem->base.import_attach ||


The field import_attach should no longer be tested for detecting 
imported buffers. Use drm_gem_is_imported() instead.


Best regards
Thomas


+   (!shmem->sparse && shmem->pages) ||
+   (shmem->sparse && !xa_empty(&shmem->xapages)));
+}
+EXPORT_SYMBOL_GPL(drm_gem_shmem_is_populated);
+
  MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
  MODULE_IMPORT_NS("DMA_BUF");
  MODULE_LICENSE("GPL v2");
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index cbe4548e3ff6..60d2b8ef230b 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -302,6 +302,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
  int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
  struct drm_mode_create_dumb *args);
  
+bool drm_gem_shmem_is_populated(struct drm_gem_shmem_object *shmem);

+
  /**
   * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
   *


--
--
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 v8 drm-dp 5/9] drm/hisilicon/hibmc: Getting connector info and EDID by using AUX channel

2025-03-31 Thread Yongbang Shi

dp->aux.name = kasprintf(GFP_KERNEL, "HIBMC DRM dp aux");

As being discussed in the feedback for v7, this is a memory leak. Can
you simply assign the string here?


Alright!



Re: [PATCH v2] drm/bridge:anx7625: Enable DSC feature

2025-03-31 Thread Dmitry Baryshkov
On Mon, Mar 31, 2025 at 05:44:58AM +, Xin Ji wrote:
> > > 4K30(3840x2160 30Hz) timing pixel clock around 297M, for 24bits RGB
> > > pixel data format, total transport bandwidth need 297M*24(at least
> > > 7.2Gbps) more than anx7625 mipi rx lane bandwidth(maximum 6Gbps,
> > > 4lanes, each lane 1.5Gbps). Without DSC function, anx7625 cannot
> > > receive 4K30 video timing.
> > >
> > > When display pixel clock exceed 250M, driver will enable DSC feature,
> > > and the compression ratio is 3:1, eg: 4K30's pixel clock around 297M,
> > > bandwidth 7.2G will be compressed to 7.2G/3 = 2.4G. Then anx7625 can
> > > receive 4K30 video timing and do decompress, then package video data
> > > and send to sink device through DP link.
> > >
> > > Anx7625 is bridge IC, sink monitor only receive normal DP signal from
> > > anx7625, sink device didn't know DSC information between SOC and
> > > anx7625
> > >
> > > v2:
> > > 1. Add more commit message
> > > 2. Remove unused code
> > > 3. Add more comment
> > 
> > This part is useless, it adds no information. It is as good as 'changed it'.
> OK, I'll remove it
> > 
> > > 4. Remove dsc_en flag
> > >
> > > Signed-off-by: Xin Ji 
> > > ---
> > >  drivers/gpu/drm/bridge/analogix/anx7625.c | 299
> > > ++  drivers/gpu/drm/bridge/analogix/anx7625.h |
> > > 31 +++
> > >  2 files changed, 274 insertions(+), 56 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > b/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > index 4be34d5c7a3b..bae76d9a665f 100644
> > > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > @@ -9,6 +9,7 @@
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > @@ -22,6 +23,7 @@
> > >
> > >  #include   #include
> > > 
> > > +#include 
> > >  #include   #include
> > >   #include  @@ -476,11
> > > +478,159 @@ static int anx7625_set_k_value(struct anx7625_data *ctx)
> > >MIPI_DIGITAL_ADJ_1, 0x3D);  }
> > >
> > > +static bool anx7625_dsc_check(struct anx7625_data *ctx) {
> > > + if (ctx->dt.pixelclock.min > DSC_PIXEL_CLOCK)
> > > + return true;
> > 
> > So, now DSC is enabled unconditionally just because the clock is too high. 
> > Let's
> > see...
> Yes
> > 
> > > +
> > > + return false;
> > > +}
> > > +
> > > +static inline int anx7625_h_timing_reg_write(struct anx7625_data *ctx,
> > > +  struct i2c_client *client,
> > > +  u8 reg_addr, u16 val,
> > > +  bool dsc_check) {
> > > + int ret;
> > > +
> > > + if (dsc_check && anx7625_dsc_check(ctx))
> > > + val = dsc_div(val);
> > > +
> > > + ret = anx7625_reg_write(ctx, client, reg_addr, val);
> > > + ret |= anx7625_reg_write(ctx, client, reg_addr + 1, val >> 8);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int anx7625_h_timing_write(struct anx7625_data *ctx,
> > > +   struct i2c_client *client,
> > > +   bool rx_h_timing) {
> > > + u16 htotal;
> > > + int ret;
> > > +
> > > + htotal = ctx->dt.hactive.min + ctx->dt.hfront_porch.min +
> > > +  ctx->dt.hback_porch.min + ctx->dt.hsync_len.min;
> > > + /* Htotal */
> > > + ret = anx7625_h_timing_reg_write(ctx, client,
> > HORIZONTAL_TOTAL_PIXELS_L,
> > > +  htotal, rx_h_timing);
> > > + /* Hactive */
> > > + ret |= anx7625_h_timing_reg_write(ctx, client,
> > HORIZONTAL_ACTIVE_PIXELS_L,
> > > +   ctx->dt.hactive.min, rx_h_timing);
> > > + /* HFP */
> > > + ret |= anx7625_h_timing_reg_write(ctx, client,
> > HORIZONTAL_FRONT_PORCH_L,
> > > +   ctx->dt.hfront_porch.min, 
> > > rx_h_timing);
> > > + /* HWS */
> > > + ret |= anx7625_h_timing_reg_write(ctx, client,
> > HORIZONTAL_SYNC_WIDTH_L,
> > > +   ctx->dt.hsync_len.min, 
> > > rx_h_timing);
> > > + /* HBP */
> > > + ret |= anx7625_h_timing_reg_write(ctx, client,
> > HORIZONTAL_BACK_PORCH_L,
> > > +   ctx->dt.hback_porch.min,
> > > + rx_h_timing);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int anx7625_v_timing_write(struct anx7625_data *ctx,
> > > +   struct i2c_client *client) {
> > > + int ret;
> > > +
> > > + /* Vactive */
> > > + ret = anx7625_reg_write(ctx, client, ACTIVE_LINES_L,
> > > + ctx->dt.vactive.min);
> > > + ret |= anx7625_reg_write(ctx, client, ACTIVE_LINES_H,
> > > +  ctx->dt.vactive.min >> 8);
> > > + /* VFP */
> > > + ret |= anx7625_reg_write(ctx, client, VERTICAL_FRONT_PORCH,
> > > + 

Re: [PATCH] drm/bridge:anx7625: Enable DSC feature

2025-03-31 Thread Dmitry Baryshkov
On Mon, Mar 31, 2025 at 03:04:07AM +, Xin Ji wrote:
> > > > > > > > > > > > > > > > > From: Dmitry Baryshkov
> > > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > > Sent: Thursday, February 13, 2025 9:04 PM
> > > > > > > > > > > > > > > > > To: Xin Ji 
> > > > > > > > > > > > > > > > > Cc: Andrzej Hajda ; 
> > > > > > > > > > > > > > > > > Neil
> > > > > > > > > > > > > > > > > Armstrong ; Robert 
> > > > > > > > > > > > > > > > > Foss
> > > > > > > > > > > > > > > > > ; Laurent Pinchart
> > > > > > > > > > > > > > > > > ; Jonas
> > Karlman
> > > > > > > > > > > > > > > > > ; Jernej Skrabec
> > > > > > > > > > > > > > > > > ; Maarten Lankhorst
> > > > > > > > > > > > > > > > > ; Maxime
> > Ripard
> > > > > > > > > > > > > > > > > ; Thomas Zimmermann
> > > > > > > > > > > > > > > > > ;
> > > > > > > > > > > > > > > David
> > > > > > > > > > > > > > > > > Airlie ; Simona Vetter
> > > > > > > > > > > > > > > > > ; Bernie Liang
> > > > > > > > > > > > > > > > > ; Qilin Wen
> > > > > > > > > > > > > > > > > ; treapk...@google.com;
> > > > > > > > > > > > > > > > > dri-devel@lists.freedesktop.org; linux-
> > > > > > > > > > > > > > > > > ker...@vger.kernel.org
> > > > > > > > > > > > > > > > > Subject: Re: [PATCH] drm/bridge:anx7625: 
> > > > > > > > > > > > > > > > > Enable
> > > > > > > > > > > > > > > > > DSC feature
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > PLease remove such splats, use something more 
> > > > > > > > > > > > > > > sensible.
> > > > > > > > > > > > > > OK, I'll change the subject
> > > > > > > > > > > > >
> > > > > > > > > > > > > It's not about the subject. Compare just "ABC DEF 
> > > > > > > > > > > > > wrote:"
> > > > > > > > > > > > > and your quatation header.
> > > > > > > > > > > > Sorry, these message is automatically added by Outlook, 
> > > > > > > > > > > > I'll
> > > > remove it.
> > > > > > > > > > > > >
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > On Thu, Feb 13, 2025 at 08:33:30PM +0800, Xin 
> > > > > > > > > > > > > > > > > Ji
> > wrote:
> > > > > > > > > > > > > > > > > > As anx7625 MIPI RX bandwidth(maximum 1.5Gbps
> > per
> > > > > > > > > > > > > > > > > > lane) and internal pixel clock(maximum 300M)
> > > > limitation.
> > > > > > > > > > > > > > > > > > Anx7625 must enable DSC feature while MIPI
> > > > > > > > > > > > > > > > > > source want to output 4K30
> > > > > > > > > > > resolution.
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > This commit message is pretty hard to read and
> > > > > > > > > > > > > > > > > understand for a non-native speaker. Please
> > > > > > > > > > > > > > > > > consider rewriting it so that it is easier to
> > > > > > > > > > > > > > > understand it.
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > Thanks for the review, sorry about that, I'll
> > > > > > > > > > > > > > > > rewriting the commit message
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > Signed-off-by: Xin Ji 
> > > > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > > > ---
> > > > > > > > > > > > > > > > > >  drivers/gpu/drm/bridge/analogix/anx7625.c 
> > > > > > > > > > > > > > > > > > | 300
> > > > > > > > > > > > > > > > > > ++
> > > > > > > > > > > > > > > > > >
> > > > > > > > ++drivers/gpu/drm/bridge/analogix/anx7625.
> > > > > > > > > > > > > > > > > > ++h
> > > > > > > > > > > > > > > > > > ++|
> > > > > > > > > > > > > > > > > > 32 +++
> > > > > > > > > > > > > > > > > >  2 files changed, 284 insertions(+), 48
> > > > > > > > > > > > > > > > > > deletions(-)
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > diff --git
> > > > > > > > > > > > > > > > > > a/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > > > > > > > > > > > > > > > > b/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > > > > > > > > > > > > > > > > index 4be34d5c7a3b..7d86ab02f71c 100644
> > > > > > > > > > > > > > > > > > --- 
> > > > > > > > > > > > > > > > > > a/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > > > > > > > > > > > > > > > > +++ 
> > > > > > > > > > > > > > > > > > b/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > > > > > > > > > > > > > > > > @@ -22,6 +22,7 @@
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > >  #include 
> > > > > > > > > > > > > > > > > > #include 
> > > > > > > > > > > > > > > > > > +#include 
> > > > > > > > > > > > > > > > > >  #include 
> > > > > > > > > > > > > > > > > > #include   #include
> > > > > > > > > > > > > > > > > >  @@
> > > > > > > > > > > > > > > > > > -476,6
> > > > > > > > > > > > > > > > > > +477,138 @@ static int
> > > > > > > > > > > > > > > > > > +anx7625_set_k_value(struct anx7625_data
> > > > > > > > > > > > > > > > > > +*ctx)
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > MIPI_DIGITAL_ADJ_1, 0x3D); }
> > > > > > >

Re: [git pull] drm for 6.15-rc1

2025-03-31 Thread Jani Nikula
On Fri, 28 Mar 2025, Linus Torvalds  wrote:
> If you want to do that hdrtest thing, do it as part of your *own*
> checks. Don't make everybody else see that disgusting thing and have
> those turds in their trees.
>
> I'll just disable it by marking it BROKEN for now. You guys can figure
> out what you want to do, but no, forcing others to see those things is
> not the answer.

Fair. I hear you.

> I would suggest you *not* make this part of the Kconfig setup and
> normal build at all, but be something where *you* can run it as part
> of your tests (ie do it as a "make drm-hdrtest" kind of thing, not as
> part of regular builds).

I would very much prefer for this to be part of the build, just hidden
behind Kconfig. We're doing build-time checks, and kbuild gives us all
the machinery to make it happen. Without the dependency tracking you'd
have to check everything every time, and that's just going to mean
people won't run it.

I suggest a Kconfig knob to truly make this opt-in, only for developers
who actually want it. Not enabled by allmodconfig or allyesconfig or
even allnoconfig. Only if you manually enable it. And yes, that's how it
should've been from the start. My bad.

Below's a patch to make it happen. We'll probably want to add more
checks like this in the future. We want to catch a whole bunch of build
issues up front. We want to be clean of e.g. W=1 and kernel-doc issues
pre-merge instead of doing extra rounds of fixes afterwards.

BR,
Jani.



>From 8c709510caab4b4ad6aa73cbcd972f32b58cad8d Mon Sep 17 00:00:00 2001
From: Jani Nikula 
Date: Mon, 31 Mar 2025 12:25:45 +0300
Subject: [PATCH] drm: add config option for extra build-time checks
Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo
Cc: Jani Nikula 

The DRM subsystem contains additional build-time checks, primarily aimed
at DRM developers and CI systems. The checks may be overzealous. They
may slow down or fail the build altogether. They may create excessive
dependency files in the build tree. They should not be enabled for
regular builds, and certainly not forced on unsuspecting developers
running an allyesconfig or allmodconfig build.

Add config DRM_DISABLE_EXTRA_BUILD_CHECKS, enabled by default as well as
by allyesconfig/allmodconfig, hiding the extra checks from anyone but
people who intentionally opt-in for the checks.

For example, to enable header tests:

$ scripts/config --disable CONFIG_DRM_DISABLE_EXTRA_BUILD_CHECKS --enable 
CONFIG_DRM_HEADER_TEST
$ make olddefconfig

Reported-by: Linus Torvalds 
Closes: 
https://lore.kernel.org/r/CAHk-=wjcdfrDTjzm6J6T-3fxtVyBG7a_0BXc2=mgoum6kpf...@mail.gmail.com
Fixes: 62ae45687e43 ("drm: ensure drm headers are self-contained and pass 
kernel-doc")
Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/Kconfig | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 2cba2b6ebe1c..5a3fce9ef998 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -489,9 +489,26 @@ config DRM_PRIVACY_SCREEN
bool
default n
 
+# Reversed option to disable on allyesconfig/allmodconfig builds
+config DRM_DISABLE_EXTRA_BUILD_CHECKS
+   bool "Disable DRM subsystem extra build-time checks"
+   default y
+   help
+ The DRM subsystem contains additional build-time checks, primarily
+ aimed at DRM developers and CI systems. The checks may be
+ overzealous. They may slow down or fail the build altogether. They may
+ create excessive dependency files in the tree. They should not be
+ enabled for regular builds, and thus they are disabled by default.
+
+# Proxy config to allow simple "depends on DRM_EXTRA_BUILD_CHECKS"
+config DRM_EXTRA_BUILD_CHECKS
+   bool
+   depends on DRM && EXPERT && DRM_DISABLE_EXTRA_BUILD_CHECKS=n
+   default !DRM_DISABLE_EXTRA_BUILD_CHECKS
+
 config DRM_WERROR
bool "Compile the drm subsystem with warnings as errors"
-   depends on DRM && EXPERT
+   depends on DRM_EXTRA_BUILD_CHECKS
depends on !WERROR
default n
help
@@ -505,7 +522,7 @@ config DRM_WERROR
 
 config DRM_HEADER_TEST
bool "Ensure DRM headers are self-contained and pass kernel-doc"
-   depends on DRM && EXPERT && BROKEN
+   depends on DRM_EXTRA_BUILD_CHECKS
default n
help
  Ensure the DRM subsystem headers both under drivers/gpu/drm and
-- 
2.39.5


-- 
Jani Nikula, Intel


Re: [PATCH 1/2] drm/panfrost: Add PM runtime flags

2025-03-31 Thread Philippe Simons



On 3/31/25 12:32, Steven Price wrote:

On 27/03/2025 12:36, Andre Przywara wrote:

On Thu, 13 Mar 2025 00:23:18 +0100
Philippe Simons  wrote:

Hi Rob, Boris, Steven,


When the GPU is the only device attached to a single power domain,
core genpd disable and enable it when gpu enter and leave runtime suspend.

Some power-domain requires a sequence before disabled,
and the reverse when enabled.

Add PM flags for CLK and RST, and implement in
panfrost_device_runtime_suspend/resume.

So some Mali configuration and integration manual I am looking at says
that this sequence should be always observed, as the powerdown sequence
would include disabling the clocks first, then asserting the reset, then
turning the power switches off (and the inverse sequence on powerup).

So should we make this unconditional, not depending on implementation
specific flags?

I think you're right, this probably should be unconditional. My only
reservation is that "it works" currently and we'd need to test this
doesn't cause regressions on existing platforms. So unless someone with
a reasonable board farm is able to do that testing I think this solution
is reasonable. So:


Should I merge both flags together then ? something like GPU_PM_RT ?



Reviewed-by: Steven Price 


And also I am wondering if panfrost_device_init() gets this wrong as well?
As I see it enabling clock first, then reset, then pm_domain, where it
should be exactly the opposite?

I agree, that looks very wrong - the power needs to be enabled before
reset is deasserted. I'm somewhat surprised we've got away with that.
Fancy writing a patch? ;)

Steve


Cheers,
Andre


Signed-off-by: Philippe Simons 
---
  drivers/gpu/drm/panfrost/panfrost_device.c | 37 ++
  drivers/gpu/drm/panfrost/panfrost_device.h |  4 +++
  2 files changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c 
b/drivers/gpu/drm/panfrost/panfrost_device.c
index a45e4addcc19..189ad2ad2b32 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -406,11 +406,38 @@ void panfrost_device_reset(struct panfrost_device *pfdev)
  static int panfrost_device_runtime_resume(struct device *dev)
  {
struct panfrost_device *pfdev = dev_get_drvdata(dev);
+   int ret;
+
+   if (pfdev->comp->pm_features & BIT(GPU_PM_RT_RST_ASRT)) {
+   ret = reset_control_deassert(pfdev->rstc);
+   if (ret)
+   return ret;
+   }
+
+   if (pfdev->comp->pm_features & BIT(GPU_PM_RT_CLK_DIS)) {
+   ret = clk_enable(pfdev->clock);
+   if (ret)
+   goto err_clk;
+
+   if (pfdev->bus_clock) {
+   ret = clk_enable(pfdev->bus_clock);
+   if (ret)
+   goto err_bus_clk;
+   }
+   }
  
  	panfrost_device_reset(pfdev);

panfrost_devfreq_resume(pfdev);
  
  	return 0;

+
+err_bus_clk:
+   if (pfdev->comp->pm_features & BIT(GPU_PM_RT_CLK_DIS))
+   clk_disable(pfdev->clock);
+err_clk:
+   if (pfdev->comp->pm_features & BIT(GPU_PM_RT_RST_ASRT))
+   reset_control_assert(pfdev->rstc);
+   return ret;
  }
  
  static int panfrost_device_runtime_suspend(struct device *dev)

@@ -426,6 +453,16 @@ static int panfrost_device_runtime_suspend(struct device 
*dev)
panfrost_gpu_suspend_irq(pfdev);
panfrost_gpu_power_off(pfdev);
  
+	if (pfdev->comp->pm_features & BIT(GPU_PM_RT_CLK_DIS)) {

+   if (pfdev->bus_clock)
+   clk_disable(pfdev->bus_clock);
+
+   clk_disable(pfdev->clock);
+   }
+
+   if (pfdev->comp->pm_features & BIT(GPU_PM_RT_RST_ASRT))
+   reset_control_assert(pfdev->rstc);
+
return 0;
  }
  
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h

index cffcb0ac7c11..f372d4819262 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -36,10 +36,14 @@ enum panfrost_drv_comp_bits {
   * enum panfrost_gpu_pm - Supported kernel power management features
   * @GPU_PM_CLK_DIS:  Allow disabling clocks during system suspend
   * @GPU_PM_VREG_OFF: Allow turning off regulators during system suspend
+ * @GPU_PM_RT_CLK_DIS: Allow disabling clocks during system runtime suspend
+ * @GPU_PM_RST_ASRT: Allow asserting the reset control during runtime suspend
   */
  enum panfrost_gpu_pm {
GPU_PM_CLK_DIS,
GPU_PM_VREG_OFF,
+   GPU_PM_RT_CLK_DIS,
+   GPU_PM_RT_RST_ASRT
  };
  
  struct panfrost_features {


Re: [PATCH 1/4] drm: adp: Replace custom compare_dev with component_compare_of

2025-03-31 Thread Janne Grunau
On Mon, Mar 31, 2025 at 05:28:45PM +0800, shao.ming...@zte.com.cn wrote:
> From: Tang Dongxing 
> 
> Remove the custom device comparison function compare_dev and replace it
> with the existing kernel helper component_compare_of
> 
> Signed-off-by: Tang Dongxing 
> Signed-off-by: Shao Mingyin 
> ---
>  drivers/gpu/drm/adp/adp_drv.c | 7 +--
>  1 file changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/adp/adp_drv.c b/drivers/gpu/drm/adp/adp_drv.c
> index c98c647f981d..32350c1a5c1f 100644
> --- a/drivers/gpu/drm/adp/adp_drv.c
> +++ b/drivers/gpu/drm/adp/adp_drv.c
> @@ -551,11 +551,6 @@ static const struct component_master_ops adp_master_ops 
> = {
>   .unbind = adp_drm_unbind,
>  };
> 
> -static int compare_dev(struct device *dev, void *data)
> -{
> - return dev->of_node == data;
> -}
> -
>  static int adp_probe(struct platform_device *pdev)
>  {
>   struct device_node *port;
> @@ -579,7 +574,7 @@ static int adp_probe(struct platform_device *pdev)
>   if (!port)
>   return -ENODEV;
> 
> - drm_of_component_match_add(&pdev->dev, &match, compare_dev, port);
> + drm_of_component_match_add(&pdev->dev, &match, component_compare_of, 
> port);
>   of_node_put(port);
> 
>   return component_master_add_with_match(&pdev->dev, &adp_master_ops, 
> match);

Reviewied-by: Janne Grunau 

thanks,
Janne


Re: [PATCH 2/2] drm/panfrost: add h616 compatible string

2025-03-31 Thread Andre Przywara
On Mon, 31 Mar 2025 11:32:58 +0100
Steven Price  wrote:

Hi Steven,

thanks for having a look!

> On 12/03/2025 23:23, Philippe Simons wrote:
> > Tie the Allwinner compatible string to the two features bits that will
> > toggle the clocks and the reset line whenever the power domain is changing
> > state.  
> 
> This looks fine, but we need the new compatible string to be documented
> in the bindings:
> 
> Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
> 
> I'm not sure what the situation is for the device tree for this
> platform, but it would be good to get that all sorted before we merge
> the compatible into panfrost.

The binding addition was sent earlier, as part of my power-domain driver
series:
https://lore.kernel.org/linux-sunxi/20250221005802.11001-1-andre.przyw...@arm.com/T/#m083df99cf34ddfd06a6a4b8fbb49636a51b05112

Rob took that one already, and it landed in Linus' tree last week, so
that would be covered.

Cheers,
Andre

> 
> Thanks,
> Steve
> 
> > Signed-off-by: Philippe Simons 
> > ---
> >  drivers/gpu/drm/panfrost/panfrost_drv.c | 8 
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
> > b/drivers/gpu/drm/panfrost/panfrost_drv.c
> > index 0f3935556ac7..f13743fe6bad 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> > +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> > @@ -776,6 +776,13 @@ static const struct panfrost_compatible default_data = 
> > {
> > .pm_domain_names = NULL,
> >  };
> >  
> > +static const struct panfrost_compatible allwinner_h616_data = {
> > +   .num_supplies = ARRAY_SIZE(default_supplies) - 1,
> > +   .supply_names = default_supplies,
> > +   .num_pm_domains = 1,
> > +   .pm_features = BIT(GPU_PM_RT_CLK_DIS) | BIT(GPU_PM_RT_RST_ASRT),
> > +};
> > +
> >  static const struct panfrost_compatible amlogic_data = {
> > .num_supplies = ARRAY_SIZE(default_supplies) - 1,
> > .supply_names = default_supplies,
> > @@ -859,6 +866,7 @@ static const struct of_device_id dt_match[] = {
> > { .compatible = "mediatek,mt8186-mali", .data = &mediatek_mt8186_data },
> > { .compatible = "mediatek,mt8188-mali", .data = &mediatek_mt8188_data },
> > { .compatible = "mediatek,mt8192-mali", .data = &mediatek_mt8192_data },
> > +   { .compatible = "allwinner,sun50i-h616-mali", .data = 
> > &allwinner_h616_data },
> > {}
> >  };
> >  MODULE_DEVICE_TABLE(of, dt_match);  
> 



Re: [PATCH 09/15] drm/panthor: Test for imported buffers with drm_gem_is_imported()

2025-03-31 Thread Steven Price
On 17/03/2025 13:06, Thomas Zimmermann wrote:
> Instead of testing import_attach for imported GEM buffers, invoke
> drm_gem_is_imported() to do the test. The helper tests the dma_buf
> itself while import_attach is just an artifact of the import. Prepares
> to make import_attach optional.
> 
> Signed-off-by: Thomas Zimmermann 
> Cc: Boris Brezillon 
> Cc: Steven Price 
> Cc: Liviu Dudau 

Reviewed-by: Steven Price 

> ---
>  drivers/gpu/drm/panthor/panthor_gem.c |  2 +-
>  drivers/gpu/drm/panthor/panthor_mmu.c | 10 +-
>  2 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panthor/panthor_gem.c 
> b/drivers/gpu/drm/panthor/panthor_gem.c
> index 8244a4e6c2a2..fd014ccc3bfc 100644
> --- a/drivers/gpu/drm/panthor/panthor_gem.c
> +++ b/drivers/gpu/drm/panthor/panthor_gem.c
> @@ -155,7 +155,7 @@ static enum drm_gem_object_status 
> panthor_gem_status(struct drm_gem_object *obj)
>   struct panthor_gem_object *bo = to_panthor_bo(obj);
>   enum drm_gem_object_status res = 0;
>  
> - if (bo->base.base.import_attach || bo->base.pages)
> + if (drm_gem_is_imported(&bo->base.base) || bo->base.pages)
>   res |= DRM_GEM_OBJECT_RESIDENT;
>  
>   return res;
> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c 
> b/drivers/gpu/drm/panthor/panthor_mmu.c
> index 12a02e28f50f..3e123159ac10 100644
> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
> @@ -1103,7 +1103,7 @@ static void panthor_vm_bo_put(struct drm_gpuvm_bo 
> *vm_bo)
>   /* If the vm_bo object was destroyed, release the pin reference that
>* was hold by this object.
>*/
> - if (unpin && !bo->base.base.import_attach)
> + if (unpin && !drm_gem_is_imported(&bo->base.base))
>   drm_gem_shmem_unpin(&bo->base);
>  
>   drm_gpuvm_put(vm);
> @@ -1234,7 +1234,7 @@ static int panthor_vm_prepare_map_op_ctx(struct 
> panthor_vm_op_ctx *op_ctx,
>   if (ret)
>   goto err_cleanup;
>  
> - if (!bo->base.base.import_attach) {
> + if (!drm_gem_is_imported(&bo->base.base)) {
>   /* Pre-reserve the BO pages, so the map operation doesn't have 
> to
>* allocate.
>*/
> @@ -1245,7 +1245,7 @@ static int panthor_vm_prepare_map_op_ctx(struct 
> panthor_vm_op_ctx *op_ctx,
>  
>   sgt = drm_gem_shmem_get_pages_sgt(&bo->base);
>   if (IS_ERR(sgt)) {
> - if (!bo->base.base.import_attach)
> + if (!drm_gem_is_imported(&bo->base.base))
>   drm_gem_shmem_unpin(&bo->base);
>  
>   ret = PTR_ERR(sgt);
> @@ -1256,7 +1256,7 @@ static int panthor_vm_prepare_map_op_ctx(struct 
> panthor_vm_op_ctx *op_ctx,
>  
>   preallocated_vm_bo = drm_gpuvm_bo_create(&vm->base, &bo->base.base);
>   if (!preallocated_vm_bo) {
> - if (!bo->base.base.import_attach)
> + if (!drm_gem_is_imported(&bo->base.base))
>   drm_gem_shmem_unpin(&bo->base);
>  
>   ret = -ENOMEM;
> @@ -1282,7 +1282,7 @@ static int panthor_vm_prepare_map_op_ctx(struct 
> panthor_vm_op_ctx *op_ctx,
>* which will be released in panthor_vm_bo_put().
>*/
>   if (preallocated_vm_bo != op_ctx->map.vm_bo &&
> - !bo->base.base.import_attach)
> + !drm_gem_is_imported(&bo->base.base))
>   drm_gem_shmem_unpin(&bo->base);
>  
>   op_ctx->map.bo_offset = offset;



Re: [PATCH] dma-buf/sw_sync: Decrement refcount on error in sw_sync_ioctl_get_deadline()

2025-03-31 Thread Christian König
Am 31.03.25 um 11:45 schrieb Dan Carpenter:
> Call dma_fence_put(fence) before returning an error on this error path.
>
> Fixes: 70e67aaec2f4 ("dma-buf/sw_sync: Add fence deadline support")
> Signed-off-by: Dan Carpenter 
> ---
>  drivers/dma-buf/sw_sync.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
> index f5905d67dedb..b7615c5c6cac 100644
> --- a/drivers/dma-buf/sw_sync.c
> +++ b/drivers/dma-buf/sw_sync.c
> @@ -438,8 +438,10 @@ static int sw_sync_ioctl_get_deadline(struct 
> sync_timeline *obj, unsigned long a
>   return -EINVAL;
>  
>   pt = dma_fence_to_sync_pt(fence);
> - if (!pt)
> + if (!pt) {
> + dma_fence_put(fence);
>   return -EINVAL;
> + }

Good catch.

I think it would be cleaner if we add an error label and then use "ret = 
-EINVAL; goto error;" here as well as a few lines below when ret is set to 
-ENOENT.

This way we can also avoid the ret = 0 in the declaration and let the compiler 
actually check the lifetime of the assignment.

Regards,
Christian.

>  
>   spin_lock_irqsave(fence->lock, flags);
>   if (test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) {



[PATCH 1/4] drm: adp: Replace custom compare_dev with component_compare_of

2025-03-31 Thread shao.mingyin
From: Tang Dongxing 

Remove the custom device comparison function compare_dev and replace it
with the existing kernel helper component_compare_of

Signed-off-by: Tang Dongxing 
Signed-off-by: Shao Mingyin 
---
 drivers/gpu/drm/adp/adp_drv.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/adp/adp_drv.c b/drivers/gpu/drm/adp/adp_drv.c
index c98c647f981d..32350c1a5c1f 100644
--- a/drivers/gpu/drm/adp/adp_drv.c
+++ b/drivers/gpu/drm/adp/adp_drv.c
@@ -551,11 +551,6 @@ static const struct component_master_ops adp_master_ops = {
.unbind = adp_drm_unbind,
 };

-static int compare_dev(struct device *dev, void *data)
-{
-   return dev->of_node == data;
-}
-
 static int adp_probe(struct platform_device *pdev)
 {
struct device_node *port;
@@ -579,7 +574,7 @@ static int adp_probe(struct platform_device *pdev)
if (!port)
return -ENODEV;

-   drm_of_component_match_add(&pdev->dev, &match, compare_dev, port);
+   drm_of_component_match_add(&pdev->dev, &match, component_compare_of, 
port);
of_node_put(port);

return component_master_add_with_match(&pdev->dev, &adp_master_ops, 
match);
-- 
2.25.1


Re: [PATCH] drm/i915/gem: Convert SPDX headers to single-line format

2025-03-31 Thread Andi Shyti
Hi,

On Fri, Mar 28, 2025 at 12:26:29AM +0100, Andi Shyti wrote:
> Replace multi-line SPDX license headers with single-line
> equivalents (// SPDX-License-Identifier: MIT or /* ... */ for
> headers), as preferred by current kernel coding style.
> 
> Signed-off-by: Andi Shyti 

merged to drm-intel-gt-next.

Andi


[PATCH v2] drm/amdkfd: Change svm_range_get_info return type

2025-03-31 Thread Ваторопин Андрей
From: Andrey Vatoropin 

Static analysis shows that pointer "svms" cannot be NULL because it points
to the object "struct svm_range_list". Remove the extra NULL check. It is
meaningless and harms the readability of the code.

In the function svm_range_get_info() there is no possibility of failure.
Therefore, the caller of the function svm_range_get_info() does not need
a return value. Change the function svm_range_get_info() return type from
"int" to "void". 

Since the function svm_range_get_info() has a return type of "void". The
caller of the function svm_range_get_info() does not need a return value.
Delete extra code.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Signed-off-by: Andrey Vatoropin 
---
v1 -> v2: also change return type of svm_range_get_info() per Felix Kuehling 
suggestion

 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c |  4 +---
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c |  7 ++-
 drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 11 +--
 3 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 1e9dd00620bf..a2149afa5803 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -2039,9 +2039,7 @@ static int criu_get_process_object_info(struct 
kfd_process *p,
 
num_events = kfd_get_num_events(p);
 
-   ret = svm_range_get_info(p, &num_svm_ranges, &svm_priv_data_size);
-   if (ret)
-   return ret;
+   svm_range_get_info(p, &num_svm_ranges, &svm_priv_data_size);
 
*num_objects = num_queues + num_events + num_svm_ranges;
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 100717a98ec1..1b7d57a1b245 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -4076,8 +4076,8 @@ int kfd_criu_restore_svm(struct kfd_process *p,
return ret;
 }
 
-int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
-  uint64_t *svm_priv_data_size)
+void svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
+   uint64_t *svm_priv_data_size)
 {
uint64_t total_size, accessibility_size, common_attr_size;
int nattr_common = 4, nattr_accessibility = 1;
@@ -4089,8 +4089,6 @@ int svm_range_get_info(struct kfd_process *p, uint32_t 
*num_svm_ranges,
*svm_priv_data_size = 0;
 
svms = &p->svms;
-   if (!svms)
-   return -EINVAL;
 
mutex_lock(&svms->lock);
list_for_each_entry(prange, &svms->list, list) {
@@ -4132,7 +4130,6 @@ int svm_range_get_info(struct kfd_process *p, uint32_t 
*num_svm_ranges,
 
pr_debug("num_svm_ranges %u total_priv_size %llu\n", *num_svm_ranges,
 *svm_priv_data_size);
-   return 0;
 }
 
 int kfd_criu_checkpoint_svm(struct kfd_process *p,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
index 6ea23c78009c..01c7a4877904 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
@@ -184,8 +184,8 @@ void schedule_deferred_list_work(struct svm_range_list 
*svms);
 void svm_range_dma_unmap_dev(struct device *dev, dma_addr_t *dma_addr,
 unsigned long offset, unsigned long npages);
 void svm_range_dma_unmap(struct svm_range *prange);
-int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
-  uint64_t *svm_priv_data_size);
+void svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
+   uint64_t *svm_priv_data_size);
 int kfd_criu_checkpoint_svm(struct kfd_process *p,
uint8_t __user *user_priv_data,
uint64_t *priv_offset);
@@ -237,13 +237,12 @@ static inline int svm_range_schedule_evict_svm_bo(
return -EINVAL;
 }
 
-static inline int svm_range_get_info(struct kfd_process *p,
-uint32_t *num_svm_ranges,
-uint64_t *svm_priv_data_size)
+static inline void svm_range_get_info(struct kfd_process *p,
+ uint32_t *num_svm_ranges,
+ uint64_t *svm_priv_data_size)
 {
*num_svm_ranges = 0;
*svm_priv_data_size = 0;
-   return 0;
 }
 
 static inline int kfd_criu_checkpoint_svm(struct kfd_process *p,
-- 
2.43.0


Re: [PATCH 00/18] drm: Provide helpers for system framebuffers and add efidrm/vesadrm

2025-03-31 Thread Thomas Zimmermann

Hi

Am 19.03.25 um 13:50 schrieb nerdopolis:
[...]

FYI When this gets merged,
https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/hw/xfree86/common/xf86platformBus.c?ref_type=heads#L589
might need to be updated to add exceptions for vesadrm and efidrm like there
is for simpledrm.
I am willing to open a merge request, but freedesktop is readonly for now
during their migration.


I've sent out an MR with this update.

Best regards
Thomas







--
--
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 v3 1/4] drm/panel: Add new helpers for refcounted panel allocatons

2025-03-31 Thread Maxime Ripard
On Sun, Mar 30, 2025 at 10:24:12PM -0400, Anusha Srivatsa wrote:
> diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> index 
> a9c042c8dea1a82ef979c7a68204e0b55483fc28..97a5457b64fbbe9c91c6a4f41b8e1fbfe4fa604e
>  100644
> --- a/include/drm/drm_panel.h
> +++ b/include/drm/drm_panel.h
> @@ -268,6 +268,30 @@ struct drm_panel {
>   bool enabled;
>  };
>  
> +void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
> +  const struct drm_panel_funcs *funcs,
> +  int connector_type);
> +
> +/**
> + * devm_drm_panel_alloc - Allocate and initialize a refcounted panel.
> + * The reference count is initialised to 1 and is automatically  given back
> + * by devm action.

No. I told you in my previous email that it needed to be between the arguments 
and returns
sections ...

> + * @dev: struct device of the panel device
> + * @type: the type of the struct which contains struct &drm_panel
> + * @member: the name of the &drm_panel within @type
> + * @funcs: callbacks for this panel
> + * @connector_type: the connector type (DRM_MODE_CONNECTOR_*) corresponding 
> to
> + * the panel interface

... So here, just like you did for all the other functions you introduced.

Also, there's no reference counting yet, so that paragraph should be in
your second patch.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v6] drm/dp: clamp PWM bit count to advertised MIN and MAX capabilities

2025-03-31 Thread Johan Hovold
On Sun, Mar 30, 2025 at 08:31:07PM +0100, Christopher Obbard wrote:
> According to the eDP specification (VESA Embedded DisplayPort Standard
> v1.4b, Section 3.3.10.2), if the value of DP_EDP_PWMGEN_BIT_COUNT is
> less than DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, the sink is required to use
> the MIN value as the effective PWM bit count.
> 
> This commit updates the logic to clamp the reported
> DP_EDP_PWMGEN_BIT_COUNT to the range defined by _CAP_MIN and _CAP_MAX.
> 
> As part of this change, the behavior is modified such that reading both
> _CAP_MIN and _CAP_MAX registers is now required to succeed, otherwise
> bl->max value could end up being not set although
> drm_edp_backlight_probe_max() returned success.
> 
> This ensures correct handling of eDP panels that report a zero PWM
> bit count but still provide valid non-zero MIN and MAX capability
> values. Without this clamping, brightness values may be interpreted
> incorrectly, leading to a dim or non-functional backlight.
> 
> For example, the Samsung ATNA40YK20 OLED panel used in the Lenovo
> ThinkPad T14s Gen6 (Snapdragon) reports a PWM bit count of 0, but
> supports AUX backlight control and declares a valid 11-bit range.
> Clamping ensures brightness scaling works as intended on such panels.
> 
> Co-developed-by: Rui Miguel Silva 
> Signed-off-by: Rui Miguel Silva 
> Signed-off-by: Christopher Obbard 

> @@ -4035,6 +4036,32 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, 
> struct drm_edp_backlight_inf
>   }
>  
>   pn &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
> +
> + ret = drm_dp_dpcd_read_byte(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, 
> &pn_min);
> + if (ret < 0) {
> + drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count 
> cap min: %d\n",
> + aux->name, ret);
> + return -ENODEV;
> + }
> + pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
> +
> + ret = drm_dp_dpcd_read_byte(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, 
> &pn_max);
> + if (ret < 0) {
> + drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count 
> cap max: %d\n",
> + aux->name, ret);
> + return -ENODEV;
> + }
> + pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
> +
> + /*
> +  * Per VESA eDP Spec v1.4b, section 3.3.10.2:
> +  * If DP_EDP_PWMGEN_BIT_COUNT is less than 
> DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN,
> +  * the sink must use the MIN value as the effective PWM bit count.
> +  * Clamp the reported value to the [MIN, MAX] capability range to ensure
> +  * correct brightness scaling on compliant eDP panels.
> +  */
> + pn = clamp(pn, pn_min, pn_max);

You never make sure that pn_min <= pn_max so you could end up with
pn < pn_min on broken hardware here. Not sure if it's something you need
to worry about at this point.

> +
>   bl->max = (1 << pn) - 1;
>   if (!driver_pwm_freq_hz)
>   return 0;

Otherwise this looks correct to me and does not break backlight control
on the X1E reference design:

Reviewed-by: Johan Hovold 
Tested-by: Johan Hovold 

Johan


RE: [PATCH v15 0/6] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl

2025-03-31 Thread Cavitt, Jonathan
-Original Message-
From: Landwerlin, Lionel G  
Sent: Monday, March 31, 2025 1:18 AM
To: Cavitt, Jonathan ; intel...@lists.freedesktop.org
Cc: Gupta, saurabhg ; Zuo, Alex ; 
joonas.lahti...@linux.intel.com; Brost, Matthew ; 
Zhang, Jianxun ; Lin, Shuicheng 
; dri-devel@lists.freedesktop.org; Wajdeczko, Michal 
; Mrozek, Michal ; Jadav, 
Raag ; Harrison, John C 
Subject: Re: [PATCH v15 0/6] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl
> 
> Hi Jonathan,
> 
> Are the pagefault reported for any unit in the GPU (including command 
> streamer?) or is it limited to execution units?

Currently, the only faults that are reported are pagefaults that are handled by
the XE pagefault handler (pf_queue_work_func), and that are reported on a 
userspace-visible engine class (I.E. not "reserved").  So, I think that means 
only
execution unit pagefaults are visible?
-Jonathan Cavitt

> 
> Thanks,
> 
> -Lionel
> 
> On 28/03/2025 22:40, Jonathan Cavitt wrote:
> > Add additional information to each VM so they can report up to the first
> > 50 seen faults.  Only pagefaults are saved this way currently, though in
> > the future, all faults should be tracked by the VM for future reporting.
> >
> > Additionally, of the pagefaults reported, only failed pagefaults are
> > saved this way, as successful pagefaults should recover silently and not
> > need to be reported to userspace.
> >
> > To allow userspace to access these faults, a new ioctl -
> > xe_vm_get_property_ioct - was created.
> >
> > v2: (Matt Brost)
> > - Break full ban list request into a separate property.
> > - Reformat drm_xe_vm_get_property struct.
> > - Remove need for drm_xe_faults helper struct.
> > - Separate data pointer and scalar return value in ioctl.
> > - Get address type on pagefault report and save it to the pagefault.
> > - Correctly reject writes to read-only VMAs.
> > - Miscellaneous formatting fixes.
> >
> > v3: (Matt Brost)
> > - Only allow querying of failed pagefaults
> >
> > v4:
> > - Remove unnecessary size parameter from helper function, as it
> >is a property of the arguments. (jcavitt)
> > - Remove unnecessary copy_from_user (Jainxun)
> > - Set address_precision to 1 (Jainxun)
> > - Report max size instead of dynamic size for memory allocation
> >purposes.  Total memory usage is reported separately.
> >
> > v5:
> > - Return int from xe_vm_get_property_size (Shuicheng)
> > - Fix memory leak (Shuicheng)
> > - Remove unnecessary size variable (jcavitt)
> >
> > v6:
> > - Free vm after use (Shuicheng)
> > - Compress pf copy logic (Shuicheng)
> > - Update fault_unsuccessful before storing (Shuicheng)
> > - Fix old struct name in comments (Shuicheng)
> > - Keep first 50 pagefaults instead of last 50 (Jianxun)
> > - Rename ioctl to xe_vm_get_faults_ioctl (jcavitt)
> >
> > v7:
> > - Avoid unnecessary execution by checking MAX_PFS earlier (jcavitt)
> > - Fix double-locking error (jcavitt)
> > - Assert kmemdump is successful (Shuicheng)
> > - Repair and move fill_faults break condition (Dan Carpenter)
> > - Free vm after use (jcavitt)
> > - Combine assertions (jcavitt)
> > - Expand size check in xe_vm_get_faults_ioctl (jcavitt)
> > - Remove return mask from fill_faults, as return is already -EFAULT or 0
> >(jcavitt)
> >
> > v8:
> > - Revert back to using drm_xe_vm_get_property_ioctl
> > - s/Migrate/Move (Michal)
> > - s/xe_pagefault/xe_gt_pagefault (Michal)
> > - Create new header file, xe_gt_pagefault_types.h (Michal)
> > - Add and fix kernel docs (Michal)
> > - Rename xe_vm.pfs to xe_vm.faults (jcavitt)
> > - Store fault data and not pagefault in xe_vm faults list (jcavitt)
> > - Store address, address type, and address precision per fault (jcavitt)
> > - Store engine class and instance data per fault (Jianxun)
> > - Properly handle kzalloc error (Michal W)
> > - s/MAX_PFS/MAX_FAULTS_SAVED_PER_VM (Michal W)
> > - Store fault level per fault (Micahl M)
> > - Apply better copy_to_user logic (jcavitt)
> >
> > v9:
> > - More kernel doc fixes (Michal W, Jianxun)
> > - Better error handling (jcavitt)
> >
> > v10:
> > - Convert enums to defines in regs folder (Michal W)
> > - Move xe_guc_pagefault_desc to regs folder (Michal W)
> > - Future-proof size logic for zero-size properties (jcavitt)
> > - Replace address type extern with access type (Jianxun)
> > - Add fault type to xe_drm_fault (Jianxun)
> >
> > v11:
> > - Remove unnecessary switch case logic (Raag)
> > - Compress size get, size validation, and property fill functions into a
> >single helper function (jcavitt)
> > - Assert valid size (jcavitt)
> > - Store pagefaults in non-fault-mode VMs as well (Jianxun)
> >
> > v12:
> > - Remove unnecessary else condition
> > - Correct backwards helper function size logic (jcavitt)
> > - Fix kernel docs and comments (Michal W)
> >
> > v13:
> > - Move xe and user engine class mapping arrays to header (John H)
> >
> > v14:
> > - Fix double locking issue (Jianxun)
> > - Use size_t instead of int (Raag)
> > - Remove unnecessary includes (j

Re: [PATCH 17/18] drm/sysfb: vesadrm: Add EDID support

2025-03-31 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

> Enable the connector's EDID property if edid_info contains valid
> data. Exports the EDID via sysfs for user-space compositors.
>
> EDID information is not always available. Depending on the system
> and kernel configuration, it is either provided by the boot loader
> or read by the kernel during early boot stages.
>
> There's only one VESA display, so EDID data always belongs to this
> output.
>
> Signed-off-by: Thomas Zimmermann 
> ---

Reviewed-by: Javier Martinez Canillas 

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH v4 03/11] drm/fourcc: Add DRM_FORMAT_Y8

2025-03-31 Thread Pekka Paalanen
On Thu, 27 Mar 2025 17:35:39 +0100
Geert Uytterhoeven  wrote:

> Hi Pekka,
> 
> On Thu, 27 Mar 2025 at 16:59, Pekka Paalanen
>  wrote:
> > On Thu, 27 Mar 2025 16:21:16 +0200
> > Tomi Valkeinen  wrote:  
> > > On 27/03/2025 11:20, Pekka Paalanen wrote:  
> > > > On Wed, 26 Mar 2025 15:55:18 +0200
> > > > Tomi Valkeinen  wrote:  
> > > >> On 26/03/2025 15:52, Geert Uytterhoeven wrote:  
> > > >>> On Wed, 26 Mar 2025 at 14:23, Tomi Valkeinen
> > > >>>  wrote:  
> > >  Add greyscale Y8 format.
> > > 
> > >  Acked-by: Dmitry Baryshkov 
> > >  Signed-off-by: Tomi Valkeinen   
> > > >>>
> > > >>> Thanks for your patch!
> > > >>>  
> > >  --- a/include/uapi/drm/drm_fourcc.h
> > >  +++ b/include/uapi/drm/drm_fourcc.h
> > >  @@ -405,6 +405,9 @@ extern "C" {
> > > #define DRM_FORMAT_YUV444  fourcc_code('Y', 'U', '2', '4') /* 
> > >  non-subsampled Cb (1) and Cr (2) planes */
> > > #define DRM_FORMAT_YVU444  fourcc_code('Y', 'V', '2', '4') /* 
> > >  non-subsampled Cr (1) and Cb (2) planes */
> > > 
> > >  +/* Greyscale formats */
> > >  +
> > >  +#define DRM_FORMAT_Y8  fourcc_code('G', 'R', 'E', 'Y')  /* 
> > >  8-bit Y-only */  
> > > >>>
> > > >>> This format differs from e.g. DRM_FORMAT_R8, which encodes
> > > >>> the number of bits in the FOURCC format. What do you envision
> > > >>> for e.g. DRM_FORMAT_Y16? fourcc_code('G', 'R', '1', '6')?  
> > > >>
> > > >> I wanted to use the same fourcc as on V4L2 side. Strictly speaking it's
> > > >> not required, but different fourccs for the same formats do confuse.
> > > >>
> > > >> So, generally speaking, I'd pick an existing fourcc from v4l2 side if
> > > >> possible, and if not, invent a new one.  
> > > >
> > > > what's the actual difference between DRM_FORMAT_R8 and DRM_FORMAT_Y8?
> > > >
> > > > Is the difference that when R8 gets expanded to RGB, it becomes (R, 0,
> > > > 0), but Y8 gets expanded to (c1 * Y, c2 * Y, c3 * Y) where c1..c3 are
> > > > defined by MatrixCoefficients (H.273 terminology)?
> > > >
> > > > That would be my intuitive assumption following how YCbCr is handled.
> > > > Is it obvious enough, or should there be a comment to that effect?  
> > >
> > > You raise an interesting point. Is it defined how a display driver, that
> > > supports R8 as a format, shows R8 on screen? I came into this in the
> > > context of grayscale formats, so I thought R8 would be handled as (R, R,
> > > R) in RGB. But you say (R, 0, 0), which... also makes sense.  
> >
> > That is a good question too. I based my assumption on OpenGL behavior
> > of R8.
> >
> > Single channel displays do exist I believe, but being single-channel,
> > expansion on the other channels is likely meaningless. Hm, but for the
> > KMS color pipeline, it would be meaningful, like with a CTM.
> > Interesting.
> >
> > I don't know. Maybe Geert does?  
> 
> I did some digging, and was a bit surprised that it was you who told
> me to use R8 instead of Y8?
> https://lore.kernel.org/all/20220202111954.6ee9a10c@eldfell

Hi Geert,

indeed I did. I never thought of the question of expansion to R,G,B
before. Maybe that expansion is what spells R8 and Y8 apart?

I do think that expansion needs to be specified, so that the KMS color
pipeline computations are defined. There is a big difference between
multiplying these with an arbitrary 3x3 matrix (e.g. CTM):

- (R, 0, 0)
- (R, R, R)
- (c1 * Y, c2 * Y, c3 * Y)

I forgot to consider that in the discussion of single-channel displays,
because the displays obviously do not consider any other channel than
the one.

Using DRM_FORMAT_Y8 FB with a single-channel display might even be
surprising, because the proposed Y8 definition would result in c1 * Y,
and not Y. The default c1 comes from the BT.601 matrix IIRC?

Therefore I think the difference between R8 and Y8 has been found. Now
we just need to determine whether R8 means (R, 0, 0) or (R, R, R) to
nail down the color operations as well. There are questions like what
is the outcome at the video signal level when we have one KMS plane
with an R8 FB and another KMS plane with an RGBA FB on the same
CRTC? What about Y8 or NV12 in the mix? What if the video signal is
single-channel, RGB, or YCbCr?


Thanks,
pq


pgp7h_tyyvvlz.pgp
Description: OpenPGP digital signature


[PATCH v9 drm-dp 9/9] drm/hisilicon/hibmc: Add vga connector detect functions

2025-03-31 Thread Yongbang Shi
From: Baihan Li 

Because the connected VGA connector would make driver can't get the
userspace call, adding detect_ctx in vga connector to make HPD active
userspace.

Signed-off-by: Baihan Li 
Signed-off-by: Yongbang Shi 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c 
b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 05e19ea4c9f9..e8a527ede854 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -60,6 +60,7 @@ static void hibmc_connector_destroy(struct drm_connector 
*connector)
 static const struct drm_connector_helper_funcs
hibmc_connector_helper_funcs = {
.get_modes = hibmc_connector_get_modes,
+   .detect_ctx = drm_connector_helper_detect_from_ddc,
 };
 
 static const struct drm_connector_funcs hibmc_connector_funcs = {
@@ -127,5 +128,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv)
 
drm_connector_attach_encoder(connector, encoder);
 
+   connector->polled = DRM_CONNECTOR_POLL_CONNECT | 
DRM_CONNECTOR_POLL_DISCONNECT;
+
return 0;
 }
-- 
2.33.0



Re: [PATCH v15 0/6] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl

2025-03-31 Thread Lionel Landwerlin

Hi Jonathan,

Are the pagefault reported for any unit in the GPU (including command 
streamer?) or is it limited to execution units?


Thanks,

-Lionel

On 28/03/2025 22:40, Jonathan Cavitt wrote:

Add additional information to each VM so they can report up to the first
50 seen faults.  Only pagefaults are saved this way currently, though in
the future, all faults should be tracked by the VM for future reporting.

Additionally, of the pagefaults reported, only failed pagefaults are
saved this way, as successful pagefaults should recover silently and not
need to be reported to userspace.

To allow userspace to access these faults, a new ioctl -
xe_vm_get_property_ioct - was created.

v2: (Matt Brost)
- Break full ban list request into a separate property.
- Reformat drm_xe_vm_get_property struct.
- Remove need for drm_xe_faults helper struct.
- Separate data pointer and scalar return value in ioctl.
- Get address type on pagefault report and save it to the pagefault.
- Correctly reject writes to read-only VMAs.
- Miscellaneous formatting fixes.

v3: (Matt Brost)
- Only allow querying of failed pagefaults

v4:
- Remove unnecessary size parameter from helper function, as it
   is a property of the arguments. (jcavitt)
- Remove unnecessary copy_from_user (Jainxun)
- Set address_precision to 1 (Jainxun)
- Report max size instead of dynamic size for memory allocation
   purposes.  Total memory usage is reported separately.

v5:
- Return int from xe_vm_get_property_size (Shuicheng)
- Fix memory leak (Shuicheng)
- Remove unnecessary size variable (jcavitt)

v6:
- Free vm after use (Shuicheng)
- Compress pf copy logic (Shuicheng)
- Update fault_unsuccessful before storing (Shuicheng)
- Fix old struct name in comments (Shuicheng)
- Keep first 50 pagefaults instead of last 50 (Jianxun)
- Rename ioctl to xe_vm_get_faults_ioctl (jcavitt)

v7:
- Avoid unnecessary execution by checking MAX_PFS earlier (jcavitt)
- Fix double-locking error (jcavitt)
- Assert kmemdump is successful (Shuicheng)
- Repair and move fill_faults break condition (Dan Carpenter)
- Free vm after use (jcavitt)
- Combine assertions (jcavitt)
- Expand size check in xe_vm_get_faults_ioctl (jcavitt)
- Remove return mask from fill_faults, as return is already -EFAULT or 0
   (jcavitt)

v8:
- Revert back to using drm_xe_vm_get_property_ioctl
- s/Migrate/Move (Michal)
- s/xe_pagefault/xe_gt_pagefault (Michal)
- Create new header file, xe_gt_pagefault_types.h (Michal)
- Add and fix kernel docs (Michal)
- Rename xe_vm.pfs to xe_vm.faults (jcavitt)
- Store fault data and not pagefault in xe_vm faults list (jcavitt)
- Store address, address type, and address precision per fault (jcavitt)
- Store engine class and instance data per fault (Jianxun)
- Properly handle kzalloc error (Michal W)
- s/MAX_PFS/MAX_FAULTS_SAVED_PER_VM (Michal W)
- Store fault level per fault (Micahl M)
- Apply better copy_to_user logic (jcavitt)

v9:
- More kernel doc fixes (Michal W, Jianxun)
- Better error handling (jcavitt)

v10:
- Convert enums to defines in regs folder (Michal W)
- Move xe_guc_pagefault_desc to regs folder (Michal W)
- Future-proof size logic for zero-size properties (jcavitt)
- Replace address type extern with access type (Jianxun)
- Add fault type to xe_drm_fault (Jianxun)

v11:
- Remove unnecessary switch case logic (Raag)
- Compress size get, size validation, and property fill functions into a
   single helper function (jcavitt)
- Assert valid size (jcavitt)
- Store pagefaults in non-fault-mode VMs as well (Jianxun)

v12:
- Remove unnecessary else condition
- Correct backwards helper function size logic (jcavitt)
- Fix kernel docs and comments (Michal W)

v13:
- Move xe and user engine class mapping arrays to header (John H)

v14:
- Fix double locking issue (Jianxun)
- Use size_t instead of int (Raag)
- Remove unnecessary includes (jcavitt)

v15:
- Do not report faults from reserved engines (Jianxun)

Signed-off-by: Jonathan Cavitt 
Suggested-by: Joonas Lahtinen 
Suggested-by: Matthew Brost 
Cc: Zhang Jianxun 
Cc: Shuicheng Lin 
Cc: Michal Wajdeczko 
Cc: Michal Mrozek 
Cc: Raag Jadav 
Cc: John Harrison 

Jonathan Cavitt (6):
   drm/xe/xe_hw_engine: Map xe and user engine class in header
   drm/xe/xe_gt_pagefault: Disallow writes to read-only VMAs
   drm/xe/xe_gt_pagefault: Move pagefault struct to header
   drm/xe/uapi: Define drm_xe_vm_get_property
   drm/xe/xe_vm: Add per VM fault info
   drm/xe/xe_vm: Implement xe_vm_get_property_ioctl

  drivers/gpu/drm/xe/regs/xe_pagefault_desc.h |  50 ++
  drivers/gpu/drm/xe/xe_device.c  |   3 +
  drivers/gpu/drm/xe/xe_gt_pagefault.c|  72 
  drivers/gpu/drm/xe/xe_gt_pagefault_types.h  |  42 +
  drivers/gpu/drm/xe/xe_guc_fwif.h|  28 
  drivers/gpu/drm/xe/xe_hw_engine.c   |  24 ++-
  drivers/gpu/drm/xe/xe_hw_engine_types.h |   3 +
  drivers/gpu/drm/xe/xe_query.c   |  18 +-
  drivers/gpu/drm/xe/xe_vm.c  | 177 
  driv

Re: [PATCH v4 03/11] drm/fourcc: Add DRM_FORMAT_Y8

2025-03-31 Thread Laurent Pinchart
On Mon, Mar 31, 2025 at 10:54:46AM +0300, Pekka Paalanen wrote:
> On Thu, 27 Mar 2025 17:35:39 +0100
> Geert Uytterhoeven  wrote:
> 
> > Hi Pekka,
> > 
> > On Thu, 27 Mar 2025 at 16:59, Pekka Paalanen
> >  wrote:
> > > On Thu, 27 Mar 2025 16:21:16 +0200
> > > Tomi Valkeinen  wrote:  
> > > > On 27/03/2025 11:20, Pekka Paalanen wrote:  
> > > > > On Wed, 26 Mar 2025 15:55:18 +0200
> > > > > Tomi Valkeinen  wrote:  
> > > > >> On 26/03/2025 15:52, Geert Uytterhoeven wrote:  
> > > > >>> On Wed, 26 Mar 2025 at 14:23, Tomi Valkeinen
> > > > >>>  wrote:  
> > > >  Add greyscale Y8 format.
> > > > 
> > > >  Acked-by: Dmitry Baryshkov 
> > > >  Signed-off-by: Tomi Valkeinen   
> > > > >>>
> > > > >>> Thanks for your patch!
> > > > >>>  
> > > >  --- a/include/uapi/drm/drm_fourcc.h
> > > >  +++ b/include/uapi/drm/drm_fourcc.h
> > > >  @@ -405,6 +405,9 @@ extern "C" {
> > > > #define DRM_FORMAT_YUV444  fourcc_code('Y', 'U', '2', '4') 
> > > >  /* non-subsampled Cb (1) and Cr (2) planes */
> > > > #define DRM_FORMAT_YVU444  fourcc_code('Y', 'V', '2', '4') 
> > > >  /* non-subsampled Cr (1) and Cb (2) planes */
> > > > 
> > > >  +/* Greyscale formats */
> > > >  +
> > > >  +#define DRM_FORMAT_Y8  fourcc_code('G', 'R', 'E', 'Y')  
> > > >  /* 8-bit Y-only */  
> > > > >>>
> > > > >>> This format differs from e.g. DRM_FORMAT_R8, which encodes
> > > > >>> the number of bits in the FOURCC format. What do you envision
> > > > >>> for e.g. DRM_FORMAT_Y16? fourcc_code('G', 'R', '1', '6')?  
> > > > >>
> > > > >> I wanted to use the same fourcc as on V4L2 side. Strictly speaking 
> > > > >> it's
> > > > >> not required, but different fourccs for the same formats do confuse.
> > > > >>
> > > > >> So, generally speaking, I'd pick an existing fourcc from v4l2 side if
> > > > >> possible, and if not, invent a new one.  
> > > > >
> > > > > what's the actual difference between DRM_FORMAT_R8 and DRM_FORMAT_Y8?
> > > > >
> > > > > Is the difference that when R8 gets expanded to RGB, it becomes (R, 0,
> > > > > 0), but Y8 gets expanded to (c1 * Y, c2 * Y, c3 * Y) where c1..c3 are
> > > > > defined by MatrixCoefficients (H.273 terminology)?
> > > > >
> > > > > That would be my intuitive assumption following how YCbCr is handled.
> > > > > Is it obvious enough, or should there be a comment to that effect?  
> > > >
> > > > You raise an interesting point. Is it defined how a display driver, that
> > > > supports R8 as a format, shows R8 on screen? I came into this in the
> > > > context of grayscale formats, so I thought R8 would be handled as (R, R,
> > > > R) in RGB. But you say (R, 0, 0), which... also makes sense.  
> > >
> > > That is a good question too. I based my assumption on OpenGL behavior
> > > of R8.
> > >
> > > Single channel displays do exist I believe, but being single-channel,
> > > expansion on the other channels is likely meaningless. Hm, but for the
> > > KMS color pipeline, it would be meaningful, like with a CTM.
> > > Interesting.
> > >
> > > I don't know. Maybe Geert does?  
> > 
> > I did some digging, and was a bit surprised that it was you who told
> > me to use R8 instead of Y8?
> > https://lore.kernel.org/all/20220202111954.6ee9a10c@eldfell
> 
> Hi Geert,
> 
> indeed I did. I never thought of the question of expansion to R,G,B
> before. Maybe that expansion is what spells R8 and Y8 apart?
> 
> I do think that expansion needs to be specified, so that the KMS color
> pipeline computations are defined. There is a big difference between
> multiplying these with an arbitrary 3x3 matrix (e.g. CTM):
> 
> - (R, 0, 0)
> - (R, R, R)
> - (c1 * Y, c2 * Y, c3 * Y)

I'd be very surprised by an YUV to RGB conversion matrix where the first
column would contain different values. What we need to take into account
though is quantization (full vs. limited range).

> I forgot to consider that in the discussion of single-channel displays,
> because the displays obviously do not consider any other channel than
> the one.
> 
> Using DRM_FORMAT_Y8 FB with a single-channel display might even be
> surprising, because the proposed Y8 definition would result in c1 * Y,
> and not Y. The default c1 comes from the BT.601 matrix IIRC?
> 
> Therefore I think the difference between R8 and Y8 has been found. Now
> we just need to determine whether R8 means (R, 0, 0) or (R, R, R) to
> nail down the color operations as well. There are questions like what
> is the outcome at the video signal level when we have one KMS plane
> with an R8 FB and another KMS plane with an RGBA FB on the same
> CRTC? What about Y8 or NV12 in the mix? What if the video signal is
> single-channel, RGB, or YCbCr?

-- 
Regards,

Laurent Pinchart


[PATCH v9 drm-dp 6/9] drm/hisilicon/hibmc: Add colorbar-cfg feature and its debugfs file

2025-03-31 Thread Yongbang Shi
From: Baihan Li 

DP controller can support generating a color bar signal over the
DisplayPort interface. This can be useful to check for possible DDR
or GPU problems, as the signal generator resides completely in the DP
block. Add debugfs file that controls colorbar generator.

echo: config the color bar register to display
cat: print the color bar configuration

Signed-off-by: Baihan Li 
Signed-off-by: Yongbang Shi 
Reviewed-by: Dmitry Baryshkov 
---
ChangeLog:
v3 -> v4:
  - add comments in hibmc_control_write(), suggested by Dmitry Baryshkov.
v2 -> v3:
  - rewrite the commit log, suggested by Dmitry Baryshkov.
  - move colorbar debugfs entry to this patch, suggested by Dmitry Baryshkov.
  - change binary format to integer format, suggested by Dmitry Baryshkov.
v1 -> v2:
  - add colorbar introduction in commit, suggested by Dmitry Baryshkov.
  - splittting colorbar and debugfs in different patches, suggested by Dmitry 
Baryshkov.
  - deleting edid decoder and its debugfs, suggested by Dmitry Baryshkov.
  - using debugfs_init() callback, suggested by Dmitry Baryshkov.
---
 drivers/gpu/drm/hisilicon/hibmc/Makefile  |   3 +-
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c|  43 
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h|  29 +
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h   |   3 +
 .../drm/hisilicon/hibmc/hibmc_drm_debugfs.c   | 104 ++
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c|   1 +
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |   2 +
 7 files changed, 184 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_debugfs.c

diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile 
b/drivers/gpu/drm/hisilicon/hibmc/Makefile
index 43de077d6769..1f65c683282f 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/Makefile
+++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_i2c.o 
\
-  dp/dp_aux.o dp/dp_link.o dp/dp_hw.o dp/dp_serdes.o hibmc_drm_dp.o
+  dp/dp_aux.o dp/dp_link.o dp/dp_hw.o dp/dp_serdes.o 
hibmc_drm_dp.o \
+  hibmc_drm_debugfs.o
 
 obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index aa9354a996c9..ce7cb07815b2 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -226,3 +226,46 @@ int hibmc_dp_mode_set(struct hibmc_dp *dp, struct 
drm_display_mode *mode)
 
return 0;
 }
+
+static const struct hibmc_dp_color_raw g_rgb_raw[] = {
+   {CBAR_COLOR_BAR, 0x000, 0x000, 0x000},
+   {CBAR_WHITE, 0xfff, 0xfff, 0xfff},
+   {CBAR_RED,   0xfff, 0x000, 0x000},
+   {CBAR_ORANGE,0xfff, 0x800, 0x000},
+   {CBAR_YELLOW,0xfff, 0xfff, 0x000},
+   {CBAR_GREEN, 0x000, 0xfff, 0x000},
+   {CBAR_CYAN,  0x000, 0x800, 0x800},
+   {CBAR_BLUE,  0x000, 0x000, 0xfff},
+   {CBAR_PURPLE,0x800, 0x000, 0x800},
+   {CBAR_BLACK, 0x000, 0x000, 0x000},
+};
+
+void hibmc_dp_set_cbar(struct hibmc_dp *dp, const struct hibmc_dp_cbar_cfg 
*cfg)
+{
+   struct hibmc_dp_dev *dp_dev = dp->dp_dev;
+   struct hibmc_dp_color_raw raw_data;
+
+   if (cfg->enable) {
+   hibmc_dp_reg_write_field(dp_dev, HIBMC_DP_COLOR_BAR_CTRL, 
BIT(9),
+cfg->self_timing);
+   hibmc_dp_reg_write_field(dp_dev, HIBMC_DP_COLOR_BAR_CTRL, 
GENMASK(8, 1),
+cfg->dynamic_rate);
+   if (cfg->pattern == CBAR_COLOR_BAR) {
+   hibmc_dp_reg_write_field(dp_dev, 
HIBMC_DP_COLOR_BAR_CTRL, BIT(10), 0);
+   } else {
+   raw_data = g_rgb_raw[cfg->pattern];
+   drm_dbg_dp(dp->drm_dev, "r:%x g:%x b:%x\n", 
raw_data.r_value,
+  raw_data.g_value, raw_data.b_value);
+   hibmc_dp_reg_write_field(dp_dev, 
HIBMC_DP_COLOR_BAR_CTRL, BIT(10), 1);
+   hibmc_dp_reg_write_field(dp_dev, 
HIBMC_DP_COLOR_BAR_CTRL, GENMASK(23, 12),
+raw_data.r_value);
+   hibmc_dp_reg_write_field(dp_dev, 
HIBMC_DP_COLOR_BAR_CTRL1, GENMASK(23, 12),
+raw_data.g_value);
+   hibmc_dp_reg_write_field(dp_dev, 
HIBMC_DP_COLOR_BAR_CTRL1, GENMASK(11, 0),
+raw_data.b_value);
+   }
+   }
+
+   hibmc_dp_reg_write_field(dp_dev, HIBMC_DP_COLOR_BAR_CTRL, BIT(0), 
cfg->enable);
+   writel(HIBMC_DP_SYNC_EN_MASK, dp_dev->base + HIBMC_DP_TIMING_SYNC_CTRL);
+}
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
index 53b6d0beecea..83a53dae8012 100644
--- a/drivers/gp

[PATCH v9 drm-dp 5/9] drm/hisilicon/hibmc: Getting connector info and EDID by using AUX channel

2025-03-31 Thread Yongbang Shi
From: Baihan Li 

Add registering drm_aux and use it to get connector edid with drm
functions. Add ddc channel in connector initialization to put drm_aux
in drm_connector.

Signed-off-by: Baihan Li 
Signed-off-by: Yongbang Shi 
Reviewed-by: Dmitry Baryshkov 
---
ChangeLog:
v8 -> v9:
  - fix the leak problem in hibmc_dp_aux_init(), suggested by Jani Nikula
v7 -> v8:
  - use drm_edid_read() in hibmc_dp_connector_get_modes(), suggested by Jani 
Nikula
v6 -> v7:
  - add if statement about drm aux in hibmc_dp_connector_get_modes(), suggested 
by Jani Nikula
v5 -> v6:
  - move the detect_ctx() to the patch 7/9.
v2 -> v3:
  - Capitalized EDID and AUX, suggested by Dmitry Baryshkov.
v1 -> v2:
  - deleting type conversion, suggested by Dmitry Baryshkov.
  - deleting hibmc_dp_connector_get_modes() and using 
drm_connector_helper_get_modes(), suggested by Dmitry Baryshkov.
---
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c   |  3 +-
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c| 31 ---
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  5 +++
 3 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c
index ded9e7ce887a..8732cd1d8cb6 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c
@@ -161,7 +161,8 @@ void hibmc_dp_aux_init(struct hibmc_dp *dp)
 HIBMC_DP_MIN_PULSE_NUM);
 
dp->aux.transfer = hibmc_dp_aux_xfer;
-   dp->aux.is_remote = 0;
+   dp->aux.name = "HIBMC DRM dp aux";
+   dp->aux.drm_dev = dp->drm_dev;
drm_dp_aux_init(&dp->aux);
dp->dp_dev->aux = &dp->aux;
 }
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c 
b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
index 603d6b198a54..8e5ee816dfbd 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
@@ -15,11 +15,16 @@
 
 static int hibmc_dp_connector_get_modes(struct drm_connector *connector)
 {
+   const struct drm_edid *drm_edid;
int count;
 
-   count = drm_add_modes_noedid(connector, 
connector->dev->mode_config.max_width,
-connector->dev->mode_config.max_height);
-   drm_set_preferred_mode(connector, 1024, 768); // temporary 
implementation
+   drm_edid = drm_edid_read(connector);
+
+   drm_edid_connector_update(connector, drm_edid);
+
+   count = drm_edid_connector_add_modes(connector);
+
+   drm_edid_free(drm_edid);
 
return count;
 }
@@ -28,12 +33,28 @@ static const struct drm_connector_helper_funcs 
hibmc_dp_conn_helper_funcs = {
.get_modes = hibmc_dp_connector_get_modes,
 };
 
+static int hibmc_dp_late_register(struct drm_connector *connector)
+{
+   struct hibmc_dp *dp = to_hibmc_dp(connector);
+
+   return drm_dp_aux_register(&dp->aux);
+}
+
+static void hibmc_dp_early_unregister(struct drm_connector *connector)
+{
+   struct hibmc_dp *dp = to_hibmc_dp(connector);
+
+   drm_dp_aux_unregister(&dp->aux);
+}
+
 static const struct drm_connector_funcs hibmc_dp_conn_funcs = {
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+   .late_register = hibmc_dp_late_register,
+   .early_unregister = hibmc_dp_early_unregister,
 };
 
 static inline int hibmc_dp_prepare(struct hibmc_dp *dp, struct 
drm_display_mode *mode)
@@ -103,8 +124,8 @@ int hibmc_dp_init(struct hibmc_drm_private *priv)
 
drm_encoder_helper_add(encoder, &hibmc_dp_encoder_helper_funcs);
 
-   ret = drm_connector_init(dev, connector, &hibmc_dp_conn_funcs,
-DRM_MODE_CONNECTOR_DisplayPort);
+   ret = drm_connector_init_with_ddc(dev, connector, &hibmc_dp_conn_funcs,
+ DRM_MODE_CONNECTOR_DisplayPort, 
&dp->aux.ddc);
if (ret) {
drm_err(dev, "init dp connector failed: %d\n", ret);
return ret;
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h 
b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index d982f1e4b958..3ddd71aada66 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -47,6 +47,11 @@ static inline struct hibmc_vdac *to_hibmc_vdac(struct 
drm_connector *connector)
return container_of(connector, struct hibmc_vdac, connector);
 }
 
+static inline struct hibmc_dp *to_hibmc_dp(struct drm_connector *connector)
+{
+   return container_of(connector, struct hibmc_dp, connector);
+}
+
 static inline struct hibmc_drm_private *to_hibmc_drm_private(struct drm_device 
*dev)
 {
return container_of(dev, struct hibmc_drm_private, d

Re: [PATCH v3 1/2] arm64: dts: qcom: x1e78100-t14s: add hpd gpio to eDP panel

2025-03-31 Thread Johan Hovold
On Thu, Mar 27, 2025 at 04:56:53PM +, Christopher Obbard wrote:
> The eDP panel has an HPD GPIO. Describe it in the device tree
> for the generic T14s model, as the HPD GPIO property is used in
> both the OLED and LCD models which inherit this device tree.

AFAICT, this patch is not correct as the hotplug detect signal is
connected directly to the display controller on (these) Qualcomm SoCs
and is already handled by its driver.

Describing it as you do here leads to less accurate delays, see commits:

2327b13d6c47 ("drm/panel-edp: Take advantage of wait_hpd_asserted() in 
struct drm_dp_aux").
3b5765df375c ("drm/panel: atna33xc20: Take advantage of 
wait_hpd_asserted() in struct drm_dp_aux")

Perhaps you lose some other functionality too.
 
> Reviewed-by: Bryan O'Donoghue 
> Signed-off-by: Christopher Obbard 
> ---
>  arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi | 11 +++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi 
> b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> index 
> 962fb050c55c4fd33f480a21a8c47a484d0c82b8..46c73f5c039ed982b553636cf8c4237a20ba7687
>  100644
> --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> @@ -980,8 +980,12 @@ &mdss_dp3 {
>   aux-bus {
>   panel: panel {
>   compatible = "edp-panel";
> + hpd-gpios = <&tlmm 119 GPIO_ACTIVE_HIGH>;
>   power-supply = <&vreg_edp_3p3>;
>  
> + pinctrl-0 = <&edp_hpd_n_default>;
> + pinctrl-names = "default";
> +
>   port {
>   edp_panel_in: endpoint {
>   remote-endpoint = <&mdss_dp3_out>;
> @@ -1286,6 +1290,13 @@ hall_int_n_default: hall-int-n-state {
>   bias-disable;
>   };
>  
> + edp_hpd_n_default: edp-hpd-n-state {
> + pins = "gpio119";
> + function = "gpio";
> + drive-strength = <2>;
> + bias-pull-up;
> + };

I checked the firmware configuration for this pin on my T14s, which
does not match what you have here. Instead the function is set to
"edp0_hot" which forwards the signal to the display controller which
already handles the signal on panel power on. (And there is also no
internal pull up enabled).

We may want to describe this pin configuration somewhere, but that's a
separate issue.

Johan


[PATCH v9 drm-dp 0/9] Add HPD, getting EDID, colorbar features in DP function

2025-03-31 Thread Yongbang Shi
From: Baihan Li 

To support DP HPD, edid printing, and colorbar display features based on
the Hisislcon DP devices.
---
ChangeLog:
v8 -> v9:
  - modify the adaptation of hibmc_dp_link_reduce_rate().
  - fix the leak problem in hibmc_dp_aux_init(), suggested by Jani Nikula.
  v8: 
https://lore.kernel.org/all/20250320101455.2538835-1-shiyongb...@huawei.com/
v7 -> v8:
  - use drm_edid_read() in hibmc_dp_connector_get_modes(), suggested by Jani 
Nikula
  v7: 
https://lore.kernel.org/all/20250319032435.1119469-1-shiyongb...@huawei.com/
v6 -> v7:
  - add if statement about drm aux in hibmc_dp_connector_get_modes(), suggested 
by Jani Nikula
  v6: 
https://lore.kernel.org/all/20250310040138.2025715-1-shiyongb...@huawei.com/
v5 -> v6:
  - fix the DP_SERDES_VOL2_PRE0 value after electrical test.
  - move the detect_ctx() to the patch 7/9.
  - add detect_ctx with 200ms delay, suggested by Dmitry Baryshkov.
  v5: 
https://lore.kernel.org/all/20250307101640.4003229-1-shiyongb...@huawei.com/
v4 -> v5:
  - add commit log about hibmc_kms_init(), suggested by Dmitry Baryshkov.
  - fix the format of block comments, suggested by Dmitry Baryshkov.
  - add hibmc_dp_get_serdes_rate_cfg() to correct transferring serdes cfg.
  - separate the vga part commit, suggested by Dmitry Baryshkov.
  - remove pci_disable_msi() in hibmc_unload()
  v4: 
https://lore.kernel.org/all/20250305112647.2344438-1-shiyongb...@huawei.com/
v3 -> v4:
  - fix the serdes cfg in hibmc_dp_serdes_set_tx_cfg(), suggested by Dmitry 
Baryshkov.
  - move the dp serdes registers to dp_reg.h, suggested by Dmitry Baryshkov.
  - add comments for if-statement of dp_init(), suggested by Dmitry Baryshkov.
  - fix the comment log to imperative sentence, suggested by Dmitry Baryshkov.
  - add comments in hibmc_control_write(), suggested by Dmitry Baryshkov.
  - add link reset of rates and lanes in pre link training process, suggested 
by Dmitry Baryshkov.
  - add vdac detect and connected/disconnected status to enable HPD process, 
suggested by Dmitry Baryshkov.
  - remove a drm_client, suggested by Dmitry Baryshkov.
  - fix build errors reported by kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202502231304.bczv4y8d-...@intel.com/
  v3: 
https://lore.kernel.org/all/20250222025102.1519798-1-shiyongb...@huawei.com/
v2 -> v3:
  - restructuring the header p_reg.h, suggested by Dmitry Baryshkov.
  - add commit log about dp serdes, suggested by Dmitry Baryshkov.
  - return value in hibmc_dp_serdes_init(), suggested by Dmitry Baryshkov.
  - add static const in the array of serdes_tx_cfg[], suggested by Dmitry 
Baryshkov.
  - change drm_warn to drm_dbg_dp, suggested by Dmitry Baryshkov.
  - add explanations about dp serdes macros, suggested by Dmitry Baryshkov.
  - change commit to an imperative sentence, suggested by Dmitry Baryshkov.
  - put HIBMC_DP_HOST_SERDES_CTRL in dp_serdes.h, suggested by Dmitry Baryshkov.
  - split the patch into two parts, suggested by Dmitry Baryshkov.
  - Capitalized EDID and AUX, suggested by Dmitry Baryshkov.
  - rewrite the commit log, suggested by Dmitry Baryshkov.
  - move colorbar debugfs entry to this patch, suggested by Dmitry Baryshkov.
  - change binary format to integer format, suggested by Dmitry Baryshkov.
  - remove mdelay(100) hpd function in ISR, suggested by Dmitry Baryshkov.
  - remove enble_display in ISR, suggested by Dmitry Baryshkov.
  - change drm_kms_helper_connector_hotplug_event() to
drm_connector_helper_hpd_irq_event(), suggested by Dmitry Baryshkov.
  - move macros to dp_reg.h, suggested by Dmitry Baryshkov.
  - remove struct irqs, suggested by Dmitry Baryshkov.
  - split this patch into two parts, suggested by Dmitry Baryshkov.
  v2: 
https://lore.kernel.org/all/20250210144959.100551-1-shiyongb...@huawei.com/
v1 -> v2:
  - splittting the patch and add more detailed the changes in the commit 
message, suggested by Dmitry Baryshkov.
  - changing all names of dp phy to dp serdes.
  - deleting type conversion, suggested by Dmitry Baryshkov.
  - deleting hibmc_dp_connector_get_modes() and using 
drm_connector_helper_get_modes(), suggested by Dmitry Baryshkov.
  - add colorbar introduction in commit, suggested by Dmitry Baryshkov.
  - deleting edid decoder and its debugfs, suggested by Dmitry Baryshkov.
  - using debugfs_init() callback, suggested by Dmitry Baryshkov.
  - splittting colorbar and debugfs in different patches, suggested by Dmitry 
Baryshkov.
  - optimizing the description in commit message, suggested by Dmitry Baryshkov.
  - add mdelay(100) comments, suggested by Dmitry Baryshkov.
  - deleting display enable in hpd event, suggested by Dmitry Baryshkov.
  v1: 
https://lore.kernel.org/all/20250127032024.1542219-1-shiyongb...@huawei.com/
---
Baihan Li (9):
  drm/hisilicon/hibmc: Restructuring the header dp_reg.h
  drm/hisilicon/hibmc: Add dp serdes cfg to adjust serdes rate, voltage
and pre-emphasis
  drm/hisilicon/hibmc: Add dp serdes cfg in dp process
  drm/hisilicon/hibmc: Refac

[PATCH v9 drm-dp 1/9] drm/hisilicon/hibmc: Restructuring the header dp_reg.h

2025-03-31 Thread Yongbang Shi
From: Baihan Li 

Move the macros below their corresponding registers to make
them more obvious.

Signed-off-by: Baihan Li 
Signed-off-by: Yongbang Shi 
Reviewed-by: Dmitry Baryshkov 
---
ChangeLog:
v2 -> v3:
  - restructuring the header dp_reg.h, suggested by Dmitry Baryshkov.
---
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h | 98 +
 1 file changed, 60 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
index 4a515c726d52..dc2bd3f80b70 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
@@ -5,72 +5,94 @@
 #define DP_REG_H
 
 #define HIBMC_DP_AUX_CMD_ADDR  0x50
+
 #define HIBMC_DP_AUX_WR_DATA0  0x54
 #define HIBMC_DP_AUX_WR_DATA1  0x58
 #define HIBMC_DP_AUX_WR_DATA2  0x5c
 #define HIBMC_DP_AUX_WR_DATA3  0x60
 #define HIBMC_DP_AUX_RD_DATA0  0x64
+
 #define HIBMC_DP_AUX_REQ   0x74
+#define HIBMC_DP_CFG_AUX_REQ   BIT(0)
+#define HIBMC_DP_CFG_AUX_SYNC_LEN_SEL  BIT(1)
+#define HIBMC_DP_CFG_AUX_TIMER_TIMEOUT BIT(2)
+#define HIBMC_DP_CFG_AUX_MIN_PULSE_NUM GENMASK(13, 9)
+
 #define HIBMC_DP_AUX_STATUS0x78
+#define HIBMC_DP_CFG_AUX_TIMEOUT   BIT(0)
+#define HIBMC_DP_CFG_AUX_STATUSGENMASK(11, 4)
+#define HIBMC_DP_CFG_AUX_READY_DATA_BYTE   GENMASK(16, 12)
+#define HIBMC_DP_CFG_AUX   GENMASK(24, 17)
+
 #define HIBMC_DP_PHYIF_CTRL0   0xa0
+#define HIBMC_DP_CFG_SCRAMBLE_EN   BIT(0)
+#define HIBMC_DP_CFG_PAT_SEL   GENMASK(7, 4)
+#define HIBMC_DP_CFG_LANE_DATA_EN  GENMASK(11, 8)
+
 #define HIBMC_DP_VIDEO_CTRL0x100
+#define HIBMC_DP_CFG_STREAM_RGB_ENABLE BIT(1)
+#define HIBMC_DP_CFG_STREAM_VIDEO_MAPPING  GENMASK(5, 2)
+#define HIBMC_DP_CFG_STREAM_FRAME_MODE BIT(6)
+#define HIBMC_DP_CFG_STREAM_HSYNC_POLARITY BIT(7)
+#define HIBMC_DP_CFG_STREAM_VSYNC_POLARITY BIT(8)
+
 #define HIBMC_DP_VIDEO_CONFIG0 0x104
+#define HIBMC_DP_CFG_STREAM_HACTIVEGENMASK(31, 16)
+#define HIBMC_DP_CFG_STREAM_HBLANK GENMASK(15, 0)
+
 #define HIBMC_DP_VIDEO_CONFIG1 0x108
+#define HIBMC_DP_CFG_STREAM_VACTIVEGENMASK(31, 16)
+#define HIBMC_DP_CFG_STREAM_VBLANK GENMASK(15, 0)
+
 #define HIBMC_DP_VIDEO_CONFIG2 0x10c
+#define HIBMC_DP_CFG_STREAM_HSYNC_WIDTHGENMASK(15, 0)
+
 #define HIBMC_DP_VIDEO_CONFIG3 0x110
+#define HIBMC_DP_CFG_STREAM_VSYNC_WIDTHGENMASK(15, 0)
+#define HIBMC_DP_CFG_STREAM_VFRONT_PORCH   GENMASK(31, 16)
+
 #define HIBMC_DP_VIDEO_PACKET  0x114
+#define HIBMC_DP_CFG_STREAM_TU_SYMBOL_SIZE GENMASK(5, 0)
+#define HIBMC_DP_CFG_STREAM_TU_SYMBOL_FRAC_SIZEGENMASK(9, 6)
+
 #define HIBMC_DP_VIDEO_MSA00x118
+#define HIBMC_DP_CFG_STREAM_VSTART GENMASK(31, 16)
+#define HIBMC_DP_CFG_STREAM_HSTART GENMASK(15, 0)
+
 #define HIBMC_DP_VIDEO_MSA10x11c
 #define HIBMC_DP_VIDEO_MSA20x120
+
 #define HIBMC_DP_VIDEO_HORIZONTAL_SIZE 0X124
+#define HIBMC_DP_CFG_STREAM_HTOTAL_SIZEGENMASK(31, 16)
+#define HIBMC_DP_CFG_STREAM_HBLANK_SIZEGENMASK(15, 0)
+
 #define HIBMC_DP_TIMING_GEN_CONFIG00x26c
+#define HIBMC_DP_CFG_TIMING_GEN0_HACTIVE   GENMASK(31, 16)
+#define HIBMC_DP_CFG_TIMING_GEN0_HBLANKGENMASK(15, 0)
+
 #define HIBMC_DP_TIMING_GEN_CONFIG20x274
+#define HIBMC_DP_CFG_TIMING_GEN0_VACTIVE   GENMASK(31, 16)
+#define HIBMC_DP_CFG_TIMING_GEN0_VBLANKGENMASK(15, 0)
+
 #define HIBMC_DP_TIMING_GEN_CONFIG30x278
+#define HIBMC_DP_CFG_TIMING_GEN0_VFRONT_PORCH  GENMASK(31, 16)
+
 #define HIBMC_DP_HDCP_CFG  0x600
+
 #define HIBMC_DP_DPTX_RST_CTRL 0x700
+#define HIBMC_DP_CFG_AUX_RST_N BIT(4)
+
 #define HIBMC_DP_DPTX_CLK_CTRL 0x704
+
 #define HIBMC_DP_DPTX_GCTL00x708
+#define HIBMC_DP_CFG_PHY_LANE_NUM  GENMASK(2, 1)
+
 #define HIBMC_DP_INTR_ENABLE   0x720
 #define HIBMC_DP_INTR_ORIGINAL_STATUS  0x728
-#define HIBMC_DP_TIMING_MODEL_CTRL 0x884
-#define HIBMC_DP_TIMING_SYNC_CTRL  0xFF0
 
-#define HIBMC_DP_CFG_AUX_SYNC_LEN_SEL  BIT(1)
-#define HIBMC_DP_CFG_AUX_TIMER_TIMEOUT BIT(2)
-#define HIBMC_DP_CFG_STREAM_FRAME_MODE BIT(6)
-#define HIBMC_DP_CFG_AUX_MIN_PULSE_NUM GENMASK(13, 9)
-#define HIBMC_DP_CFG_LANE_DATA_EN  GENMASK(11, 8)
-#define HIBMC_DP_CFG_PHY_LANE_NUM  GENMASK(2, 1)
-#define HIBMC_DP_CFG_AUX_REQ

[PATCH v9 drm-dp 3/9] drm/hisilicon/hibmc: Add dp serdes cfg in dp process

2025-03-31 Thread Yongbang Shi
From: Baihan Li 

Add dp serdes cfg in link training process, and related adapting
and modificating. Change some init values about training, because we want
completely to negotiation process, so we start with the maximum rate and
the electrical characteristic level is 0. Because serdes default cfgs is
changed and used in hibmc_kms_init(), we changed the if-statement to check
whether the value is 0.

Signed-off-by: Baihan Li 
Signed-off-by: Yongbang Shi 
Reviewed-by: Dmitry Baryshkov 
---
ChangeLog:
v8 -> v9:
  - modify the adaptation of hibmc_dp_link_reduce_rate().
v4 -> v5:
  - add commit log about hibmc_kms_init(), suggested by Dmitry Baryshkov.
  - fix the format of block comments, suggested by Dmitry Baryshkov.
  - add hibmc_dp_get_serdes_rate_cfg() to correct transferring serdes cfg.
v3 -> v4:
  - add comments for if-statement of dp_init(), suggested by Dmitry Baryshkov.
v2 -> v3:
  - change commit to an imperative sentence, suggested by Dmitry Baryshkov.
  - put HIBMC_DP_HOST_SERDES_CTRL in dp_serdes.h, suggested by Dmitry Baryshkov.
v1 -> v2:
  - splittting the patch and add more detailed the changes in the commit 
message, suggested by Dmitry Baryshkov.
---
 .../gpu/drm/hisilicon/hibmc/dp/dp_config.h|  1 +
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c|  5 +-
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c  | 70 ---
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h   |  5 ++
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 13 ++--
 5 files changed, 77 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
index 74dd9956144e..c5feef8dc27d 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
@@ -15,5 +15,6 @@
 #define HIBMC_DP_CLK_EN0x7
 #define HIBMC_DP_SYNC_EN_MASK  0x3
 #define HIBMC_DP_LINK_RATE_CAL 27
+#define HIBMC_DP_SYNC_DELAY(lanes) ((lanes) == 0x2 ? 86 : 46)
 
 #endif
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index 3612f3c5ab23..dcb2ab5ea6bb 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -72,6 +72,9 @@ static void hibmc_dp_set_sst(struct hibmc_dp_dev *dp, struct 
drm_display_mode *m
 HIBMC_DP_CFG_STREAM_HTOTAL_SIZE, htotal_size);
hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_HORIZONTAL_SIZE,
 HIBMC_DP_CFG_STREAM_HBLANK_SIZE, hblank_size);
+   hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_PACKET,
+HIBMC_DP_CFG_STREAM_SYNC_CALIBRATION,
+HIBMC_DP_SYNC_DELAY(dp->link.cap.lanes));
 }
 
 static void hibmc_dp_link_cfg(struct hibmc_dp_dev *dp, struct drm_display_mode 
*mode)
@@ -171,7 +174,7 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
return ret;
 
dp_dev->link.cap.lanes = 0x2;
-   dp_dev->link.cap.link_rate = DP_LINK_BW_2_7;
+   dp_dev->link.cap.link_rate = DP_LINK_BW_8_1;
 
/* hdcp data */
writel(HIBMC_DP_HDCP, dp_dev->base + HIBMC_DP_HDCP_CFG);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
index f6355c16cc0a..b1fcfaa8354f 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
@@ -9,6 +9,22 @@
 
 #define HIBMC_EQ_MAX_RETRY 5
 
+static inline int hibmc_dp_get_serdes_rate_cfg(struct hibmc_dp_dev *dp)
+{
+   switch (dp->link.cap.link_rate) {
+   case DP_LINK_BW_1_62:
+   return DP_SERDES_BW_1_62;
+   case DP_LINK_BW_2_7:
+   return DP_SERDES_BW_2_7;
+   case DP_LINK_BW_5_4:
+   return DP_SERDES_BW_5_4;
+   case DP_LINK_BW_8_1:
+   return DP_SERDES_BW_8_1;
+   default:
+   return -EINVAL;
+   }
+}
+
 static int hibmc_dp_link_training_configure(struct hibmc_dp_dev *dp)
 {
u8 buf[2];
@@ -41,11 +57,7 @@ static int hibmc_dp_link_training_configure(struct 
hibmc_dp_dev *dp)
return ret >= 0 ? -EIO : ret;
}
 
-   ret = drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd);
-   if (ret)
-   drm_err(dp->dev, "dp aux read dpcd failed, ret: %d\n", ret);
-
-   return ret;
+   return 0;
 }
 
 static int hibmc_dp_link_set_pattern(struct hibmc_dp_dev *dp, int pattern)
@@ -108,7 +120,11 @@ static int hibmc_dp_link_training_cr_pre(struct 
hibmc_dp_dev *dp)
return ret;
 
for (i = 0; i < dp->link.cap.lanes; i++)
-   train_set[i] = DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+   train_set[i] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
+
+   ret = hibmc_dp_serdes_set_tx_cfg(dp, dp->link.train_set);
+   if (ret)
+   return ret;
 
ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, train_set, 
dp->link.cap.lanes);

[PATCH v9 drm-dp 8/9] drm/hisilicon/hibmc: Add MSI irq getting and requesting for HPD

2025-03-31 Thread Yongbang Shi
From: Baihan Li 

To realize HPD feature, request irq for HPD , add its handler function.
We use pci_alloc_irq_vectors() to get our msi irq, because we have two
interrupts now.

Signed-off-by: Baihan Li 
Signed-off-by: Yongbang Shi 
Reviewed-by: Dmitry Baryshkov 
---
ChangeLog:
v4 -> v5:
  - remove pci_disable_msi() in hibmc_unload()
---
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h   |  3 +
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 74 +++
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  3 +
 3 files changed, 66 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
index 5614b727a710..394b1e933c3a 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
@@ -99,6 +99,9 @@
 
 #define HIBMC_DP_TIMING_SYNC_CTRL  0xFF0
 
+#define HIBMC_DP_INTSTAT   0x1e0724
+#define HIBMC_DP_INTCLR0x1e0728
+
 /* dp serdes reg */
 #define HIBMC_DP_HOST_OFFSET   0x1
 #define HIBMC_DP_LANE0_RATE_OFFSET 0x4
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c 
b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 98b01c8aee8e..768b97f9e74a 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -32,6 +32,8 @@
 
 DEFINE_DRM_GEM_FOPS(hibmc_fops);
 
+static const char *g_irqs_names_map[HIBMC_MAX_VECTORS] = { "vblank", "hpd" };
+
 static irqreturn_t hibmc_interrupt(int irq, void *arg)
 {
struct drm_device *dev = (struct drm_device *)arg;
@@ -49,6 +51,22 @@ static irqreturn_t hibmc_interrupt(int irq, void *arg)
return IRQ_HANDLED;
 }
 
+static irqreturn_t hibmc_dp_interrupt(int irq, void *arg)
+{
+   struct drm_device *dev = (struct drm_device *)arg;
+   struct hibmc_drm_private *priv = to_hibmc_drm_private(dev);
+   u32 status;
+
+   status = readl(priv->mmio + HIBMC_DP_INTSTAT);
+   if (status) {
+   priv->dp.irq_status = status;
+   writel(status, priv->mmio + HIBMC_DP_INTCLR);
+   return IRQ_WAKE_THREAD;
+   }
+
+   return IRQ_HANDLED;
+}
+
 static int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
 struct drm_mode_create_dumb *args)
 {
@@ -251,15 +269,48 @@ static int hibmc_hw_init(struct hibmc_drm_private *priv)
return 0;
 }
 
-static int hibmc_unload(struct drm_device *dev)
+static void hibmc_unload(struct drm_device *dev)
 {
-   struct pci_dev *pdev = to_pci_dev(dev->dev);
-
drm_atomic_helper_shutdown(dev);
+}
 
-   free_irq(pdev->irq, dev);
+static int hibmc_msi_init(struct drm_device *dev)
+{
+   struct pci_dev *pdev = to_pci_dev(dev->dev);
+   char name[32] = {0};
+   int valid_irq_num;
+   int irq;
+   int ret;
 
-   pci_disable_msi(to_pci_dev(dev->dev));
+   ret = pci_alloc_irq_vectors(pdev, HIBMC_MIN_VECTORS,
+   HIBMC_MAX_VECTORS, PCI_IRQ_MSI);
+   if (ret < 0) {
+   drm_err(dev, "enabling MSI failed: %d\n", ret);
+   return ret;
+   }
+
+   valid_irq_num = ret;
+
+   for (int i = 0; i < valid_irq_num; i++) {
+   snprintf(name, ARRAY_SIZE(name) - 1, "%s-%s-%s",
+dev->driver->name, pci_name(pdev), 
g_irqs_names_map[i]);
+
+   irq = pci_irq_vector(pdev, i);
+
+   if (i)
+   /* PCI devices require shared interrupts. */
+   ret = devm_request_threaded_irq(&pdev->dev, irq,
+   hibmc_dp_interrupt,
+   hibmc_dp_hpd_isr,
+   IRQF_SHARED, name, dev);
+   else
+   ret = devm_request_irq(&pdev->dev, irq, hibmc_interrupt,
+  IRQF_SHARED, name, dev);
+   if (ret) {
+   drm_err(dev, "install irq failed: %d\n", ret);
+   return ret;
+   }
+   }
 
return 0;
 }
@@ -291,15 +342,10 @@ static int hibmc_load(struct drm_device *dev)
goto err;
}
 
-   ret = pci_enable_msi(pdev);
+   ret = hibmc_msi_init(dev);
if (ret) {
-   drm_warn(dev, "enabling MSI failed: %d\n", ret);
-   } else {
-   /* PCI devices require shared interrupts. */
-   ret = request_irq(pdev->irq, hibmc_interrupt, IRQF_SHARED,
- dev->driver->name, dev);
-   if (ret)
-   drm_warn(dev, "install irq failed: %d\n", ret);
+   drm_err(dev, "hibmc msi init failed, ret:%d\n", ret);
+   goto err;
}
 
/* reset all the states of crtc/plane/encoder/connector */

[PATCH v9 drm-dp 7/9] drm/hisilicon/hibmc: Enable this hot plug detect of irq feature

2025-03-31 Thread Yongbang Shi
From: Baihan Li 

Add HPD interrupt enable functions in drm framework, and also add
detect_ctx functions. Because of the debouncing when HPD pulled out,
add 200 ms delay in detect. Add link reset process to reset link status
when a new connector pulgged in.

Signed-off-by: Baihan Li 
Signed-off-by: Yongbang Shi 
Reviewed-by: Dmitry Baryshkov 
---
ChangeLog:
v5 -> v6:
  - add detect_ctx with 200ms delay, suggested by Dmitry Baryshkov.
v4 -> v5:
  - separate the vga part commit, suggested by Dmitry Baryshkov.
v3 -> v4:
  - add link reset of rates and lanes in pre link training process, suggested 
by Dmitry Baryshkov.
  - add vdac detect and connected/disconnected status to enable HPD process, 
suggested by Dmitry Baryshkov.
  - remove a drm_client, suggested by Dmitry Baryshkov.
  - fix build errors reported by kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202502231304.bczv4y8d-...@intel.com/
v2 -> v3:
  - remove mdelay(100) hpd function in ISR, suggested by Dmitry Baryshkov.
  - remove enble_display in ISR, suggested by Dmitry Baryshkov.
  - change drm_kms_helper_connector_hotplug_event() to
drm_connector_helper_hpd_irq_event(), suggested by Dmitry Baryshkov.
  - move macros to dp_reg.h, suggested by Dmitry Baryshkov.
  - remove struct irqs, suggested by Dmitry Baryshkov.
  - split this patch into two parts, suggested by Dmitry Baryshkov.
  - add a drm client dev to handle HPD event.
v1 -> v2:
  - optimizing the description in commit message, suggested by Dmitry Baryshkov.
  - add mdelay(100) comments, suggested by Dmitry Baryshkov.
  - deleting display enable in hpd event, suggested by Dmitry Baryshkov.
---
 .../gpu/drm/hisilicon/hibmc/dp/dp_config.h|  1 +
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c| 36 
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h|  5 +++
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c| 42 +++
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  2 +
 5 files changed, 86 insertions(+)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
index c5feef8dc27d..08f9e1caf7fc 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
@@ -16,5 +16,6 @@
 #define HIBMC_DP_SYNC_EN_MASK  0x3
 #define HIBMC_DP_LINK_RATE_CAL 27
 #define HIBMC_DP_SYNC_DELAY(lanes) ((lanes) == 0x2 ? 86 : 46)
+#define HIBMC_DP_INT_ENABLE0xc
 
 #endif
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index ce7cb07815b2..8f0daec7d174 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -189,6 +189,36 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
return 0;
 }
 
+void hibmc_dp_enable_int(struct hibmc_dp *dp)
+{
+   struct hibmc_dp_dev *dp_dev = dp->dp_dev;
+
+   writel(HIBMC_DP_INT_ENABLE, dp_dev->base + HIBMC_DP_INTR_ENABLE);
+}
+
+void hibmc_dp_disable_int(struct hibmc_dp *dp)
+{
+   struct hibmc_dp_dev *dp_dev = dp->dp_dev;
+
+   writel(0, dp_dev->base + HIBMC_DP_INTR_ENABLE);
+   writel(HIBMC_DP_INT_RST, dp_dev->base + HIBMC_DP_INTR_ORIGINAL_STATUS);
+}
+
+void hibmc_dp_hpd_cfg(struct hibmc_dp *dp)
+{
+   struct hibmc_dp_dev *dp_dev = dp->dp_dev;
+
+   hibmc_dp_reg_write_field(dp_dev, HIBMC_DP_AUX_REQ, 
HIBMC_DP_CFG_AUX_SYNC_LEN_SEL, 0x0);
+   hibmc_dp_reg_write_field(dp_dev, HIBMC_DP_AUX_REQ, 
HIBMC_DP_CFG_AUX_TIMER_TIMEOUT, 0x1);
+   hibmc_dp_reg_write_field(dp->dp_dev, HIBMC_DP_AUX_REQ, 
HIBMC_DP_CFG_AUX_MIN_PULSE_NUM, 0x9);
+   writel(HIBMC_DP_HDCP, dp_dev->base + HIBMC_DP_HDCP_CFG);
+   writel(0, dp_dev->base + HIBMC_DP_INTR_ENABLE);
+   writel(HIBMC_DP_INT_RST, dp_dev->base + HIBMC_DP_INTR_ORIGINAL_STATUS);
+   writel(HIBMC_DP_INT_ENABLE, dp_dev->base + HIBMC_DP_INTR_ENABLE);
+   writel(HIBMC_DP_DPTX_RST, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL);
+   writel(HIBMC_DP_CLK_EN, dp_dev->base + HIBMC_DP_DPTX_CLK_CTRL);
+}
+
 void hibmc_dp_display_en(struct hibmc_dp *dp, bool enable)
 {
struct hibmc_dp_dev *dp_dev = dp->dp_dev;
@@ -227,6 +257,12 @@ int hibmc_dp_mode_set(struct hibmc_dp *dp, struct 
drm_display_mode *mode)
return 0;
 }
 
+void hibmc_dp_reset_link(struct hibmc_dp *dp)
+{
+   dp->dp_dev->link.status.clock_recovered = false;
+   dp->dp_dev->link.status.channel_equalized = false;
+}
+
 static const struct hibmc_dp_color_raw g_rgb_raw[] = {
{CBAR_COLOR_BAR, 0x000, 0x000, 0x000},
{CBAR_WHITE, 0xfff, 0xfff, 0xfff},
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
index 83a53dae8012..665f5b166dfb 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
@@ -49,11 +49,16 @@ struct hibmc_dp {
void __iomem *mmio;
struct drm_dp_aux aux;
struct hibmc_dp_cbar_cfg cfg;
+   u32 

[PATCH v9 drm-dp 2/9] drm/hisilicon/hibmc: Add dp serdes cfg to adjust serdes rate, voltage and pre-emphasis

2025-03-31 Thread Yongbang Shi
From: Baihan Li 

This dp controller need features of digital-to-analog conversion and
high-speed transmission in chip by its extern serdes controller. Our
serdes cfg is relatively simple, just need two register configurations.
Don't need too much functions, like: power on/off, initialize, and some
complex configurations, so I'm not going to use the phy framework.
This serdes is inited and configured in dp initialization, and also
integrating them into link training process.

For rate changing, we can change from 1.62-8.2Gpbs by cfg reg.
For voltage and pre-emphasis levels changing, we can cfg different
serdes ffe value.

Signed-off-by: Baihan Li 
Signed-off-by: Yongbang Shi 
Reviewed-by: Dmitry Baryshkov 
---
ChangeLog:
v5 -> v6:
  - fix the DP_SERDES_VOL2_PRE0 value after electrical test.
v3 -> v4:
  - fix the serdes cfg in hibmc_dp_serdes_set_tx_cfg(), suggested by Dmitry 
Baryshkov.
  - move the dp serdes registers to dp_reg.h, suggested by Dmitry Baryshkov.
  - 
v2 -> v3:
  - add commit log about dp serdes, suggested by Dmitry Baryshkov.
  - return value in hibmc_dp_serdes_init(), suggested by Dmitry Baryshkov.
  - add static const in the array of serdes_tx_cfg[], suggested by Dmitry 
Baryshkov.
  - change drm_warn to drm_dbg_dp, suggested by Dmitry Baryshkov.
  - add explanations about dp serdes macros, suggested by Dmitry Baryshkov.
v1 -> v2:
  - splittting the patch and add more detailed the changes in the commit 
message, suggested by Dmitry Baryshkov.
  - changing all names of dp phy to dp serdes.
---
 drivers/gpu/drm/hisilicon/hibmc/Makefile  |  2 +-
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h  |  4 ++
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c|  5 ++
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h   | 23 ++
 .../gpu/drm/hisilicon/hibmc/dp/dp_serdes.c| 71 +++
 5 files changed, 104 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c

diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile 
b/drivers/gpu/drm/hisilicon/hibmc/Makefile
index 95a4ed599d98..43de077d6769 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/Makefile
+++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_i2c.o 
\
-  dp/dp_aux.o dp/dp_link.o dp/dp_hw.o hibmc_drm_dp.o
+  dp/dp_aux.o dp/dp_link.o dp/dp_hw.o dp/dp_serdes.o hibmc_drm_dp.o
 
 obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
index 2c52a4476c4d..e0c6a3b7463b 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
@@ -38,6 +38,7 @@ struct hibmc_dp_dev {
struct mutex lock; /* protects concurrent RW in 
hibmc_dp_reg_write_field() */
struct hibmc_dp_link link;
u8 dpcd[DP_RECEIVER_CAP_SIZE];
+   void __iomem *serdes_base;
 };
 
 #define dp_field_modify(reg_value, mask, val)  \
@@ -59,5 +60,8 @@ struct hibmc_dp_dev {
 
 void hibmc_dp_aux_init(struct hibmc_dp_dev *dp);
 int hibmc_dp_link_training(struct hibmc_dp_dev *dp);
+int hibmc_dp_serdes_init(struct hibmc_dp_dev *dp);
+int hibmc_dp_serdes_rate_switch(u8 rate, struct hibmc_dp_dev *dp);
+int hibmc_dp_serdes_set_tx_cfg(struct hibmc_dp_dev *dp, u8 
train_set[HIBMC_DP_LANE_NUM_MAX]);
 
 #endif
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index a8d543881c09..3612f3c5ab23 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -151,6 +151,7 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
 {
struct drm_device *drm_dev = dp->drm_dev;
struct hibmc_dp_dev *dp_dev;
+   int ret;
 
dp_dev = devm_kzalloc(drm_dev->dev, sizeof(struct hibmc_dp_dev), 
GFP_KERNEL);
if (!dp_dev)
@@ -165,6 +166,10 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
 
hibmc_dp_aux_init(dp_dev);
 
+   ret = hibmc_dp_serdes_init(dp_dev);
+   if (ret)
+   return ret;
+
dp_dev->link.cap.lanes = 0x2;
dp_dev->link.cap.link_rate = DP_LINK_BW_2_7;
 
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
index dc2bd3f80b70..16ea58903598 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
@@ -95,4 +95,27 @@
 
 #define HIBMC_DP_TIMING_SYNC_CTRL  0xFF0
 
+/* dp serdes reg */
+#define HIBMC_DP_HOST_OFFSET   0x1
+#define HIBMC_DP_LANE0_RATE_OFFSET 0x4
+#define HIBMC_DP_LANE1_RATE_OFFSET 0xc
+#define HIBMC_DP_LANE_STATUS_OFFSET0x10
+#define HIBMC_DP_PMA_LANE0_OFFSET  0x18
+#define HIBMC_DP_PMA_LANE1_OFFSET  0x1c
+#define HIBMC_DP_PMA_TXDEEMPH  GENMASK(18, 1)
+#define DP_SERDES_DONE 0x3
+
+/* dp serdes TX-Deempth C

[PATCH v9 drm-dp 4/9] drm/hisilicon/hibmc: Refactor the member of drm_aux in struct hibmc_dp

2025-03-31 Thread Yongbang Shi
From: Baihan Li 

Because the drm_aux of struct hibmc_dp_dev's member is not easy to get in
hibmc_drm_dp.c, move the drm_aux to struct hibmc_dp. Then there are some
adaptations and modifications to make this patch compile.

Signed-off-by: Baihan Li 
Signed-off-by: Yongbang Shi 
Reviewed-by: Dmitry Baryshkov 
---
ChangeLog:
v3 -> v4:
  - fix the comment log to imperative sentence, suggested by Dmitry Baryshkov.
v2 -> v3:
  - split the patch into two parts, suggested by Dmitry Baryshkov.
---
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c  | 13 +++-
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h |  6 --
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c   |  2 +-
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h   |  2 ++
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 22 ++--
 5 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c
index 0a903cce1fa9..ded9e7ce887a 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c
@@ -8,6 +8,7 @@
 #include 
 #include "dp_comm.h"
 #include "dp_reg.h"
+#include "dp_hw.h"
 
 #define HIBMC_AUX_CMD_REQ_LEN  GENMASK(7, 4)
 #define HIBMC_AUX_CMD_ADDR GENMASK(27, 8)
@@ -124,7 +125,8 @@ static int hibmc_dp_aux_parse_xfer(struct hibmc_dp_dev *dp, 
struct drm_dp_aux_ms
 /* ret >= 0 ,ret is size; ret < 0, ret is err code */
 static ssize_t hibmc_dp_aux_xfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg 
*msg)
 {
-   struct hibmc_dp_dev *dp = container_of(aux, struct hibmc_dp_dev, aux);
+   struct hibmc_dp *dp_priv = container_of(aux, struct hibmc_dp, aux);
+   struct hibmc_dp_dev *dp = dp_priv->dp_dev;
u32 aux_cmd;
int ret;
u32 val; /* val will be assigned at the beginning of readl_poll_timeout 
function */
@@ -151,14 +153,15 @@ static ssize_t hibmc_dp_aux_xfer(struct drm_dp_aux *aux, 
struct drm_dp_aux_msg *
return hibmc_dp_aux_parse_xfer(dp, msg);
 }
 
-void hibmc_dp_aux_init(struct hibmc_dp_dev *dp)
+void hibmc_dp_aux_init(struct hibmc_dp *dp)
 {
-   hibmc_dp_reg_write_field(dp, HIBMC_DP_AUX_REQ, 
HIBMC_DP_CFG_AUX_SYNC_LEN_SEL, 0x0);
-   hibmc_dp_reg_write_field(dp, HIBMC_DP_AUX_REQ, 
HIBMC_DP_CFG_AUX_TIMER_TIMEOUT, 0x1);
-   hibmc_dp_reg_write_field(dp, HIBMC_DP_AUX_REQ, 
HIBMC_DP_CFG_AUX_MIN_PULSE_NUM,
+   hibmc_dp_reg_write_field(dp->dp_dev, HIBMC_DP_AUX_REQ, 
HIBMC_DP_CFG_AUX_SYNC_LEN_SEL, 0x0);
+   hibmc_dp_reg_write_field(dp->dp_dev, HIBMC_DP_AUX_REQ, 
HIBMC_DP_CFG_AUX_TIMER_TIMEOUT, 0x1);
+   hibmc_dp_reg_write_field(dp->dp_dev, HIBMC_DP_AUX_REQ, 
HIBMC_DP_CFG_AUX_MIN_PULSE_NUM,
 HIBMC_DP_MIN_PULSE_NUM);
 
dp->aux.transfer = hibmc_dp_aux_xfer;
dp->aux.is_remote = 0;
drm_dp_aux_init(&dp->aux);
+   dp->dp_dev->aux = &dp->aux;
 }
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
index e0c6a3b7463b..4add05c7f161 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
@@ -13,6 +13,8 @@
 #include 
 #include 
 
+#include "dp_hw.h"
+
 #define HIBMC_DP_LANE_NUM_MAX 2
 
 struct hibmc_link_status {
@@ -32,7 +34,7 @@ struct hibmc_dp_link {
 };
 
 struct hibmc_dp_dev {
-   struct drm_dp_aux aux;
+   struct drm_dp_aux *aux;
struct drm_device *dev;
void __iomem *base;
struct mutex lock; /* protects concurrent RW in 
hibmc_dp_reg_write_field() */
@@ -58,7 +60,7 @@ struct hibmc_dp_dev {
mutex_unlock(&_dp->lock);   \
} while (0)
 
-void hibmc_dp_aux_init(struct hibmc_dp_dev *dp);
+void hibmc_dp_aux_init(struct hibmc_dp *dp);
 int hibmc_dp_link_training(struct hibmc_dp_dev *dp);
 int hibmc_dp_serdes_init(struct hibmc_dp_dev *dp);
 int hibmc_dp_serdes_rate_switch(u8 rate, struct hibmc_dp_dev *dp);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index dcb2ab5ea6bb..aa9354a996c9 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -167,7 +167,7 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
dp_dev->dev = drm_dev;
dp_dev->base = dp->mmio + HIBMC_DP_OFFSET;
 
-   hibmc_dp_aux_init(dp_dev);
+   hibmc_dp_aux_init(dp);
 
ret = hibmc_dp_serdes_init(dp_dev);
if (ret)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
index 4dc13b3d9875..53b6d0beecea 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct hibmc_dp_dev;
 
@@ -19,6 +20,7 @@ struct hibmc_dp {
struct drm_encoder encoder;
struct drm_connector connector;
void __iomem *mmio;
+   struct drm_dp_aux aux;
 };
 

Re: [PATCH v2] drm/bridge:anx7625: Enable DSC feature

2025-03-31 Thread Dmitry Baryshkov
On Mon, Mar 31, 2025 at 10:28:00AM +0300, Dmitry Baryshkov wrote:
> On Mon, Mar 31, 2025 at 05:44:58AM +, Xin Ji wrote:
> > > > 4K30(3840x2160 30Hz) timing pixel clock around 297M, for 24bits RGB
> > > > pixel data format, total transport bandwidth need 297M*24(at least
> > > > 7.2Gbps) more than anx7625 mipi rx lane bandwidth(maximum 6Gbps,
> > > > 4lanes, each lane 1.5Gbps). Without DSC function, anx7625 cannot
> > > > receive 4K30 video timing.
> > > >
> > > > When display pixel clock exceed 250M, driver will enable DSC feature,
> > > > and the compression ratio is 3:1, eg: 4K30's pixel clock around 297M,
> > > > bandwidth 7.2G will be compressed to 7.2G/3 = 2.4G. Then anx7625 can
> > > > receive 4K30 video timing and do decompress, then package video data
> > > > and send to sink device through DP link.
> > > >
> > > > Anx7625 is bridge IC, sink monitor only receive normal DP signal from
> > > > anx7625, sink device didn't know DSC information between SOC and
> > > > anx7625
> > > >
> > > > v2:
> > > > 1. Add more commit message
> > > > 2. Remove unused code
> > > > 3. Add more comment
> > > 
> > > This part is useless, it adds no information. It is as good as 'changed 
> > > it'.
> > OK, I'll remove it
> > > 
> > > > 4. Remove dsc_en flag
> > > >
> > > > Signed-off-by: Xin Ji 
> > > > ---
> > > >  drivers/gpu/drm/bridge/analogix/anx7625.c | 299
> > > > ++  drivers/gpu/drm/bridge/analogix/anx7625.h |
> > > > 31 +++
> > > >  2 files changed, 274 insertions(+), 56 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > > b/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > > index 4be34d5c7a3b..bae76d9a665f 100644
> > > > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> > > > @@ -9,6 +9,7 @@
> > > >  #include 
> > > >  #include 
> > > >  #include 
> > > > +#include 
> > > >  #include 
> > > >  #include 
> > > >  #include 
> > > > @@ -22,6 +23,7 @@
> > > >
> > > >  #include   #include
> > > > 
> > > > +#include 
> > > >  #include   #include
> > > >   #include  @@ -476,11
> > > > +478,159 @@ static int anx7625_set_k_value(struct anx7625_data *ctx)
> > > >MIPI_DIGITAL_ADJ_1, 0x3D);  }
> > > >
> > > > +static bool anx7625_dsc_check(struct anx7625_data *ctx) {
> > > > + if (ctx->dt.pixelclock.min > DSC_PIXEL_CLOCK)
> > > > + return true;
> > > 
> > > So, now DSC is enabled unconditionally just because the clock is too 
> > > high. Let's
> > > see...
> > Yes
> > > 
> > > > +
> > > > + return false;
> > > > +}
> > > > +
> > > > +static inline int anx7625_h_timing_reg_write(struct anx7625_data *ctx,
> > > > +  struct i2c_client *client,
> > > > +  u8 reg_addr, u16 val,
> > > > +  bool dsc_check) {
> > > > + int ret;
> > > > +
> > > > + if (dsc_check && anx7625_dsc_check(ctx))
> > > > + val = dsc_div(val);
> > > > +
> > > > + ret = anx7625_reg_write(ctx, client, reg_addr, val);
> > > > + ret |= anx7625_reg_write(ctx, client, reg_addr + 1, val >> 8);
> > > > +
> > > > + return ret;
> > > > +}
> > > > +
> > > > +static int anx7625_h_timing_write(struct anx7625_data *ctx,
> > > > +   struct i2c_client *client,
> > > > +   bool rx_h_timing) {
> > > > + u16 htotal;
> > > > + int ret;
> > > > +
> > > > + htotal = ctx->dt.hactive.min + ctx->dt.hfront_porch.min +
> > > > +  ctx->dt.hback_porch.min + ctx->dt.hsync_len.min;
> > > > + /* Htotal */
> > > > + ret = anx7625_h_timing_reg_write(ctx, client,
> > > HORIZONTAL_TOTAL_PIXELS_L,
> > > > +  htotal, rx_h_timing);
> > > > + /* Hactive */
> > > > + ret |= anx7625_h_timing_reg_write(ctx, client,
> > > HORIZONTAL_ACTIVE_PIXELS_L,
> > > > +   ctx->dt.hactive.min, 
> > > > rx_h_timing);
> > > > + /* HFP */
> > > > + ret |= anx7625_h_timing_reg_write(ctx, client,
> > > HORIZONTAL_FRONT_PORCH_L,
> > > > +   ctx->dt.hfront_porch.min, 
> > > > rx_h_timing);
> > > > + /* HWS */
> > > > + ret |= anx7625_h_timing_reg_write(ctx, client,
> > > HORIZONTAL_SYNC_WIDTH_L,
> > > > +   ctx->dt.hsync_len.min, 
> > > > rx_h_timing);
> > > > + /* HBP */
> > > > + ret |= anx7625_h_timing_reg_write(ctx, client,
> > > HORIZONTAL_BACK_PORCH_L,
> > > > +   ctx->dt.hback_porch.min,
> > > > + rx_h_timing);
> > > > +
> > > > + return ret;
> > > > +}
> > > > +
> > > > +static int anx7625_v_timing_write(struct anx7625_data *ctx,
> > > > +   struct i2c_client *client) {
> > > > + int ret;
> > > > +
> > > > + /* Vactive */
> > > > + ret = anx7625_reg

Re: [PATCH] kunit: fixes backtrace suppression test module description

2025-03-31 Thread Dan Carpenter
On Sun, Mar 30, 2025 at 01:11:59PM +0800, David Gow wrote:
> On Sat, 29 Mar 2025 at 23:06, Alessandro Carminati  
> wrote:
> >
> > Adds module description to the backtrace suppression test
> >
> > Fixes:  ("19f3496") kunit: add test cases for backtrace warning suppression
> >
> > Signed-off-by: Alessandro Carminati 
> > ---
> 
> The "Fixes" tag here should be immediately before the Signed-off-by
> line, without a newline. Also, ideally the format should be something
> like:
> Fixes: d03d078df162 ("kunit: add test cases for backtrace warning 
> suppression")
> 

Yeah.  Everyone should configure the default hash length to 12.

git config set --global core.abbrev 12

I generate my fixes tags like so:

#!/bin/bash

git log -1 --format='Fixes: %h ("%s")' $*

regards,
dan carpenter



Re: [PATCH v9 1/2] dt-bindings: arm: mediatek: Add MT8186 Ponyta Chromebook

2025-03-31 Thread AngeloGioacchino Del Regno

Il 28/03/25 10:40, Jianeng Ceng ha scritto:

Ponyta is a custom label Chromebook based on MT8186. It is a
self-developed project of Huaqin and has no fixed OEM.

Signed-off-by: Jianeng Ceng 
---
Chage in V9:
- No change.

Changes in v8:
- PATCH 1/2: Remove custom label.
- Link to 
v7:https://lore.kernel.org/all/01020191ea98a643-2d0be5d1-e00b-48e0-b823-bfe2c65b0d00-000...@eu-west-1.amazonses.com/

Chage since V6:
- No change.

Changes in v5:
- PATCH 1/2: Remove sku2147483647.
- Link to 
v4:https://lore.kernel.org/all/20240906085739.1322676-2-cengjian...@huaqin.corp-partner.google.com/

Changes in v4:
- PATCH 1/2: Add more info for Ponyta custom label in commit.
- Link to 
v3:https://lore.kernel.org/all/20240904081501.2060933-1-cengjian...@huaqin.corp-partner.google.com/

Changes in v3:
- PATCH 1/2: Modify lable to label.
- Link to 
v2:https://lore.kernel.org/all/20240903061603.3007289-1-cengjian...@huaqin.corp-partner.google.com/

Chage since V2:
- No change.

---
  Documentation/devicetree/bindings/arm/mediatek.yaml | 10 ++
  1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml 
b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 108ae5e0185d..fdc57c140af7 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -285,6 +285,16 @@ properties:
- const: google,steelix-sku393218
- const: google,steelix
- const: mediatek,mt8186
+  - description: Google Ponyta
+items:


   items:
 - enum:
 - google,ponyta-sku0
 - google,ponyta-sku1


+  - const: google,ponyta-sku0
+  - const: google,ponyta
+  - const: mediatek,mt8186


Regards,
Angelo


+  - description: Google Ponyta
+items:
+  - const: google,ponyta-sku1
+  - const: google,ponyta
+  - const: mediatek,mt8186
- description: Google Rusty (Lenovo 100e Chromebook Gen 4)
  items:
- const: google,steelix-sku196609






Re: [PATCH 10/18] drm/sysfb: Merge CRTC functions

2025-03-31 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

> Merge the CRTC functions of ofdrm and simpledrm. Replace the code
> in each driver with the shared helpers. Set up callbacks with
> initializer macros.
>
> Ofdrm supports a gamma LUT, while simpledrm does not. So far ofdrm's
> LUT size has been hard-coded in the driver CRTC's atomic_check helper.
> Now pass the size of the LUT to the sysfb device. Ofdrm's custom
> atomic_flush is still required to apply changes to the LUT. Simpledrm
> passes a LUT size of 0, which disables the gamma LUT.
>
> Signed-off-by: Thomas Zimmermann 
> ---

Reviewed-by: Javier Martinez Canillas 

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



[PATCH 3/4] drm: malidp: Replace custom compare_dev with component_compare_of

2025-03-31 Thread shao.mingyin
From: Tang Dongxing 

Remove the custom device comparison function compare_dev and replace it
with the existing kernel helper component_compare_of

Signed-off-by: Tang Dongxing 
Signed-off-by: Shao Mingyin 
---
 drivers/gpu/drm/arm/malidp_drv.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index e083021e9e99..e2e6fd1f64b0 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -910,13 +910,6 @@ static const struct component_master_ops malidp_master_ops 
= {
.unbind = malidp_unbind,
 };

-static int malidp_compare_dev(struct device *dev, void *data)
-{
-   struct device_node *np = data;
-
-   return dev->of_node == np;
-}
-
 static int malidp_platform_probe(struct platform_device *pdev)
 {
struct device_node *port;
@@ -930,7 +923,7 @@ static int malidp_platform_probe(struct platform_device 
*pdev)
if (!port)
return -ENODEV;

-   drm_of_component_match_add(&pdev->dev, &match, malidp_compare_dev,
+   drm_of_component_match_add(&pdev->dev, &match, component_compare_of,
   port);
of_node_put(port);
return component_master_add_with_match(&pdev->dev, &malidp_master_ops,
-- 
2.25.1


Re: [PATCH 12/18] drm/sysfb: ofdrm: Add EDID support

2025-03-31 Thread Thomas Zimmermann

Hi

Am 31.03.25 um 11:26 schrieb Maxime Ripard:

On Thu, Mar 20, 2025 at 02:08:56PM +0100, Thomas Zimmermann wrote:

Despite the nitpicks, overall LGTM.

Thanks for reviewing.

Since I have your attention and you're knowledgeable wrt EDID: byte 20 of
the EDID header indicates the type of output (analog, HDMI, DP, etc). I
intent to use this for setting the connector type to something better then
UNKNOWN. Does that make sense?

I don't think it would work:

   - EDID doesn't indicate the kind of KMS output (ie, source) but the
 type of sink. Ie, what the monitor is capable of dealing with, not
 what the connector can emit. If we have (passive or active) bridges
 in between, it does mean that we can have an analog sink connected
 to a digital connector.

   - Since it depends on the sink, it can change over time, ie you plug
 an analog monitor, remove it, and plug a digital one. That would
 mean changing the connector type (and thus name exposed to
 userspace) at runtime, for the same driver.

   - Since it depends on the sink, it assumes the sink vendor didn't
 botch the EDID. This one is a pretty big if :)


I see. I'd really just want this for these sysfb outputs that come from 
the firmware. They should not change much at runtime.  Right now, the 
connector is always UNKNOWN and giving some type would indicate to the 
user which display is in use. But it's not really so important.


Best regards
Thomas



Maxime


--
--
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] kunit: fixes Compilation error on s390

2025-03-31 Thread Heiko Carstens
On Sat, Mar 29, 2025 at 03:03:20PM +, Alessandro Carminati wrote:
> The current implementation of suppressing warning backtraces uses __func__,
> which is a compile-time constant only for non -fPIC compilation.
> GCC's support for this situation in position-independent code varies across
> versions and architectures.
> 
> On the s390 architecture, -fPIC is required for compilation, and support
> for this scenario is available in GCC 11 and later.
> 
> Fixes:  d8b14a2 ("bug/kunit: core support for suppressing warning backtraces")
> 
> Signed-off-by: Alessandro Carminati 
> ---
>  lib/kunit/Kconfig | 1 +
>  1 file changed, 1 insertion(+)

Acked-by: Heiko Carstens 


Re: [PATCH 14/18] drm/sysfb: Add efidrm for EFI displays

2025-03-31 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

> Add support for screen_info setups with VIDEO_TYPE_EFI. Provide the
> minimum functionality of reading modes, updating and clearing the display.
>
> There is existing support for these displays provided by simpledrm with
> CONFIG_SYSFB_SIMPLEFB=y. Using efidrm over simpledrm will allows for the
> mapping of video memory with correct caching. Simpledrm always assumes WC
> caching, while fully cached memory is possible with efidrm. Efidrm will
> also allow for the use of additional functionality provided by EFI, such
> as EDID information.
>
> In addition to efidrm, add struct pixel_format plus initializer macros.
> The type and macros describe pixel formats in a generic way on order to
> find the DRM format from the screen_info settings. Similar existing code
> in SIMPLEFB_FORMATS and fbdev is not really what is needed in efidrm,
> but SIMPLEFB_FORMATS can later be converted to struct pixel_format.
>
> Signed-off-by: Thomas Zimmermann 
> ---

Reviewed-by: Javier Martinez Canillas 

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



[PATCH] dma-buf/sw_sync: Decrement refcount on error in sw_sync_ioctl_get_deadline()

2025-03-31 Thread Dan Carpenter
Call dma_fence_put(fence) before returning an error on this error path.

Fixes: 70e67aaec2f4 ("dma-buf/sw_sync: Add fence deadline support")
Signed-off-by: Dan Carpenter 
---
 drivers/dma-buf/sw_sync.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index f5905d67dedb..b7615c5c6cac 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -438,8 +438,10 @@ static int sw_sync_ioctl_get_deadline(struct sync_timeline 
*obj, unsigned long a
return -EINVAL;
 
pt = dma_fence_to_sync_pt(fence);
-   if (!pt)
+   if (!pt) {
+   dma_fence_put(fence);
return -EINVAL;
+   }
 
spin_lock_irqsave(fence->lock, flags);
if (test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) {
-- 
2.47.2



Re: [PATCH 15/18] drm/sysfb: efidrm: Add EDID support

2025-03-31 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

> Enable the connector's EDID property if edid_info contains valid
> data. Exports the EDID via sysfs for user-space compositors.
>
> EDID information is not always available. Depending on the system
> and kernel configuration, it is either provided by the boot loader
> or read by the kernel during early boot stages.
>
> As of now, there's only one EFI display, so that EDID data always
> belongs to this output. This might change if there's ever more than
> one EFI display in the system.
>
> Signed-off-by: Thomas Zimmermann 
> ---

Reviewed-by: Javier Martinez Canillas 

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH 13/18] firmware: sysfb: Move bpp-depth calculation into screen_info helper

2025-03-31 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

> Move the calculation of the bits per pixels for screen_info into a
> helper function. This will make it available to other callers besides
> the firmware code.
>
> Signed-off-by: Thomas Zimmermann 
> ---

Reviewed-by: Javier Martinez Canillas 

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



[PATCH 0/4] Replace custom compare_dev with component_compare_of in drm

2025-03-31 Thread shao.mingyin
From: Tang Dongxing 

Remove the custom device comparison function compare_dev and replace it
with the existing kernel helper component_compare_of, as suggested in
the review feedback. This simplifies the code by eliminating redundant
logic and aligns with the pattern used in other DRM drivers like
hdlcd_drv.c and malidp_drv.c.

Tang Dongxing (4):
  drm: adp: Replace custom compare_dev with component_compare_of
  drm: arm: hdlcd: Replace custom compare_dev with component_compare_of
  drm: malidp: Replace custom compare_dev with component_compare_of
  drm: mediatek: Replace custom compare_dev with component_compare_of

 drivers/gpu/drm/adp/adp_drv.c  | 7 +--
 drivers/gpu/drm/arm/hdlcd_drv.c| 7 +--
 drivers/gpu/drm/arm/malidp_drv.c   | 9 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +--
 4 files changed, 4 insertions(+), 26 deletions(-)

-- 
2.25.1


Re: [PATCH 12/18] drm/sysfb: ofdrm: Add EDID support

2025-03-31 Thread Maxime Ripard
On Thu, Mar 20, 2025 at 02:08:56PM +0100, Thomas Zimmermann wrote:
> > Despite the nitpicks, overall LGTM.
> 
> Thanks for reviewing.
> 
> Since I have your attention and you're knowledgeable wrt EDID: byte 20 of
> the EDID header indicates the type of output (analog, HDMI, DP, etc). I
> intent to use this for setting the connector type to something better then
> UNKNOWN. Does that make sense?

I don't think it would work:

  - EDID doesn't indicate the kind of KMS output (ie, source) but the
type of sink. Ie, what the monitor is capable of dealing with, not
what the connector can emit. If we have (passive or active) bridges
in between, it does mean that we can have an analog sink connected
to a digital connector.

  - Since it depends on the sink, it can change over time, ie you plug
an analog monitor, remove it, and plug a digital one. That would
mean changing the connector type (and thus name exposed to
userspace) at runtime, for the same driver.

  - Since it depends on the sink, it assumes the sink vendor didn't
botch the EDID. This one is a pretty big if :)

Maxime


signature.asc
Description: PGP signature


Re: [PATCH 16/18] drm/sysfb: Add vesadrm for VESA displays

2025-03-31 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

> Add support for screen_info setups with VIDEO_TYPE_VLFB. Provide the
> minimum functionality of reading modes, updating and clearing the display.
>
> There is existing support for these displays provided by simpledrm with
> CONFIG_SYSFB_SIMPLEFB=y. Using vesadrm over simpledrm will allow for the
> use of additional functionality provided by VESA, such as EDID information,
> gamma correction and palette modes. This enhances the user experience and
> adds support for more display configuratons.
>
> Signed-off-by: Thomas Zimmermann 
> ---

Reviewed-by: Javier Martinez Canillas 

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH 18/18] drm/sysfb: vesadrm: Add gamma correction

2025-03-31 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

> Add palette support and export GAMMA properties via sysfs. User-space
> compositors can use this interface for programming gamma ramps or night
> mode.
>
> Vesadrm supports palette updates via VGA DAC registers or VESA palette
> calls. Up to 256 palette entries are available. Userspace always supplies
> gamma ramps of 256 entries. If the native color format does not match
> this because pixel component have less then 8 bits, vesadrm interpolates
> among the palette entries.
>
> The code uses CamelCase style in a few places to match the VESA manuals.
>
> Signed-off-by: Thomas Zimmermann 
> ---

Reviewed-by: Javier Martinez Canillas 

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



  1   2   >