[Bug 216684] amdgpu graphics freezing about every 10 seconds in 5.17 and later

2022-11-11 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=216684

--- Comment #1 from memredogan3...@gmail.com ---
Created attachment 303159
  --> https://bugzilla.kernel.org/attachment.cgi?id=303159=edit
dmesg with lts kernel

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 216684] New: amdgpu graphics freezing about every 10 seconds in 5.17 and later

2022-11-11 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=216684

Bug ID: 216684
   Summary: amdgpu graphics freezing about every 10 seconds in
5.17 and later
   Product: Drivers
   Version: 2.5
Kernel Version: 5.17 and later
  Hardware: All
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: memredogan3...@gmail.com
Regression: No

Created attachment 303158
  --> https://bugzilla.kernel.org/attachment.cgi?id=303158=edit
dmesg using 6.0.8

GPU: AMD R7 240 2GB with amdgpu 
OS: Arch Linux with a custom kernel  
Graphics freeze every 10 seconds in every kernel version after 5.17. 
tried different Desktop managers and Wayland only using older kernel version
fixed it.
watching a video mpv shows dropped frames in output.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [PATCH 3/5] drm/msm: Fix IS_ERR_OR_NULL() vs NULL check in msm_icc_get()

2022-11-11 Thread cuigaosheng

NAK. This path should be returned if it is NON-NULL, otherwise we defer
to of_icc_get() on the parent device.  See the code-comment below.


Thanks for taking time to review this patch, how do you think of the following 
changes:
 
diff --git a/drivers/gpu/drm/msm/msm_io_utils.c 
b/drivers/gpu/drm/msm/msm_io_utils.c index d02cd29ce829..a112d8c74d59 
100644 --- a/drivers/gpu/drm/msm/msm_io_utils.c +++ 
b/drivers/gpu/drm/msm/msm_io_utils.c @@ -133,7 +133,7 @@ struct 
icc_path *msm_icc_get(struct device *dev, const char *name) struct 
icc_path *path; path = of_icc_get(dev, name); - if (path) + if 
(!IS_ERR_OR_NULL(path)) return path; 


Looking forward to your reply, thanks again!

On 2022/11/11 18:02, Marijn Suijten wrote:

On 2022-11-10 17:44:43, Gaosheng Cui wrote:

The of_icc_get() function returns NULL or error pointers on error path,
so we should use IS_ERR_OR_NULL() to check the return value.

Fixes: 5ccdcecaf8f7 ("drm/msm: lookup the ICC paths in both mdp5/dpu and mdss 
devices")
Signed-off-by: Gaosheng Cui 
---
  drivers/gpu/drm/msm/msm_io_utils.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_io_utils.c 
b/drivers/gpu/drm/msm/msm_io_utils.c
index d02cd29ce829..950083b2f092 100644
--- a/drivers/gpu/drm/msm/msm_io_utils.c
+++ b/drivers/gpu/drm/msm/msm_io_utils.c
@@ -133,7 +133,7 @@ struct icc_path *msm_icc_get(struct device *dev, const char 
*name)
struct icc_path *path;
  
  	path = of_icc_get(dev, name);

-   if (path)
+   if (IS_ERR_OR_NULL(path))

NAK. This path should be returned if it is NON-NULL, otherwise we defer
to of_icc_get() on the parent device.  See the code-comment below.

- Marijn


return path;
  
  	/*

--
2.25.1


.


Re: [PATCH 1/5] drm/nouveau/nvfw/acr: make wpr_generic_header_dump() static

2022-11-11 Thread Lyude Paul
Actually hm, I think ben will need to consider pulling these into his branch
since these don't seem to apply to drm-misc-next - so presumably they're
related to some of the work that's been getting pushed recently for GSP prep

On Fri, 2022-11-11 at 17:11 +0800, Jiapeng Chong wrote:
> This symbol is not used outside of acr.c, so marks it static.
> 
> drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c:49:1: warning: no previous prototype 
> for ‘wpr_generic_header_dump’.
> 
> Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3023
> Reported-by: Abaci Robot 
> Signed-off-by: Jiapeng Chong 
> ---
>  drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c 
> b/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c
> index 83a9c48bc58c..7ac90c495737 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c
> @@ -45,7 +45,7 @@ wpr_header_v1_dump(struct nvkm_subdev *subdev, const struct 
> wpr_header_v1 *hdr)
>   nvkm_debug(subdev, "\tstatus: %d\n", hdr->status);
>  }
>  
> -void
> +static void
>  wpr_generic_header_dump(struct nvkm_subdev *subdev, const struct 
> wpr_generic_header *hdr)
>  {
>   nvkm_debug(subdev, "wprGenericHeader\n");

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [v1] drm/msm/disp/dpu1: add color management support for the crtc

2022-11-11 Thread Dmitry Baryshkov

On 11/11/2022 16:57, Kalyan Thota wrote:

Add color management support for the crtc provided there are
enough dspps that can be allocated from the catalogue.

Changes in v1:
- cache color enabled state in the dpu crtc obj (Dmitry)
- simplify dspp allocation while creating crtc (Dmitry)
- register for color when crtc is created (Dmitry)

Signed-off-by: Kalyan Thota 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c|  5 +--
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  6 ++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  7 ++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 53 -
  4 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 4170fbe..ca4c3b3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1571,7 +1571,7 @@ static const struct drm_crtc_helper_funcs 
dpu_crtc_helper_funcs = {
  
  /* initialize crtc */

  struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane 
*plane,
-   struct drm_plane *cursor)
+   struct drm_plane *cursor, unsigned long 
features)
  {
struct drm_crtc *crtc = NULL;
struct dpu_crtc *dpu_crtc = NULL;
@@ -1583,6 +1583,7 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, 
struct drm_plane *plane,
  
  	crtc = _crtc->base;

crtc->dev = dev;
+   dpu_crtc->color_enabled = features & BIT(DPU_DSPP_PCC);
  
  	spin_lock_init(_crtc->spin_lock);

atomic_set(_crtc->frame_pending, 0);
@@ -1604,7 +1605,7 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, 
struct drm_plane *plane,
  
  	drm_crtc_helper_add(crtc, _crtc_helper_funcs);
  
-	drm_crtc_enable_color_mgmt(crtc, 0, true, 0);

+   drm_crtc_enable_color_mgmt(crtc, 0, dpu_crtc->color_enabled, 0);
  
  	/* save user friendly CRTC name for later */

snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 539b68b..342f9ae 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -136,6 +136,7 @@ struct dpu_crtc_frame_event {
   * @enabled   : whether the DPU CRTC is currently enabled. updated in the
   *  commit-thread, not state-swap time which is earlier, so
   *  safe to make decisions on during VBLANK on/off work
+ * @color_enabled : whether crtc supports color management
   * @feature_list  : list of color processing features supported on a crtc
   * @active_list   : list of color processing features are active
   * @dirty_list: list of color processing features are dirty
@@ -164,7 +165,7 @@ struct dpu_crtc {
u64 play_count;
ktime_t vblank_cb_time;
bool enabled;
-
+   bool color_enabled;
struct list_head feature_list;
struct list_head active_list;
struct list_head dirty_list;
@@ -269,10 +270,11 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc);
   * @dev: dpu device
   * @plane: base plane
   * @cursor: cursor plane
+ * @features: color features
   * @Return: new crtc object or error
   */
  struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane 
*plane,
-  struct drm_plane *cursor);
+  struct drm_plane *cursor, unsigned long 
features);
  
  /**

   * dpu_crtc_register_custom_event - api for enabling/disabling crtc event
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index c9058aa..d72edb8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -579,6 +579,7 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
  static struct msm_display_topology dpu_encoder_get_topology(
struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms,
+   struct dpu_crtc *dpu_crtc,
struct drm_display_mode *mode)
  {
struct msm_display_topology topology = {0};
@@ -607,7 +608,7 @@ static struct msm_display_topology dpu_encoder_get_topology(
else
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
  
-	if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) {

+   if (dpu_crtc->color_enabled) {
if (dpu_kms->catalog->dspp &&
(dpu_kms->catalog->dspp_count >= topology.num_lm))
topology.num_dspp = topology.num_lm;
@@ -642,6 +643,7 @@ static int dpu_encoder_virt_atomic_check(
struct drm_display_mode *adj_mode;
struct msm_display_topology topology;
struct dpu_global_state *global_state;
+   struct dpu_crtc *dpu_crtc;
int i = 0;
int ret = 0;
  
@@ 

Re: [PATCH 1/5] drm/nouveau/nvfw/acr: make wpr_generic_header_dump() static

2022-11-11 Thread Lyude Paul
For the whole series:

Reviewed-by: Lyude Paul 

Will push to drm-misc-next in a bit

On Fri, 2022-11-11 at 17:11 +0800, Jiapeng Chong wrote:
> This symbol is not used outside of acr.c, so marks it static.
> 
> drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c:49:1: warning: no previous prototype 
> for ‘wpr_generic_header_dump’.
> 
> Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3023
> Reported-by: Abaci Robot 
> Signed-off-by: Jiapeng Chong 
> ---
>  drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c 
> b/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c
> index 83a9c48bc58c..7ac90c495737 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c
> @@ -45,7 +45,7 @@ wpr_header_v1_dump(struct nvkm_subdev *subdev, const struct 
> wpr_header_v1 *hdr)
>   nvkm_debug(subdev, "\tstatus: %d\n", hdr->status);
>  }
>  
> -void
> +static void
>  wpr_generic_header_dump(struct nvkm_subdev *subdev, const struct 
> wpr_generic_header *hdr)
>  {
>   nvkm_debug(subdev, "wprGenericHeader\n");

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [v1] drm/msm/disp/dpu1: populate disp_info with connector type

2022-11-11 Thread Dmitry Baryshkov

On 11/11/2022 16:56, Kalyan Thota wrote:

Populate disp_info with connector type. Since DRM encoder type
for few encoders can be similar (like eDP and DP) this information
will be useful to differentiate interfaces.

Changes in v1:
- add connector type in the disp_info (Dmitry)


You can get connector type from


- add helper functions to know encoder type
- update commit text reflecting the change

Signed-off-by: Kalyan Thota 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 44 +++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 26 +++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 ++
  drivers/gpu/drm/msm/dp/dp_display.c |  5 
  drivers/gpu/drm/msm/msm_drv.h   |  7 -
  5 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 9c6817b..c9058aa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -217,6 +217,40 @@ static u32 dither_matrix[DITHER_MATRIX_SZ] = {
15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10
  };
  
+bool dpu_encoder_is_external(struct drm_encoder *drm_enc)

+{
+   struct dpu_encoder_virt *dpu_enc;
+
+   if (!drm_enc)
+   return false;
+
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+   return (dpu_enc->disp_info.connector_type ==
+   DRM_MODE_CONNECTOR_DisplayPort);


And also HDMI, DVI, VGA and several other connector types.

It is much easier to enumerate non-interesting (in other words, 
non-external ones):

- Unknown
- LVDS
- eDP
- DSI
- DPI
- VIRTUAL
- WRITEBACK


+}
+
+bool dpu_encoder_is_virtual(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc;
+
+   if (!drm_enc)
+   return false;
+
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+   return (dpu_enc->disp_info.connector_type == 
DRM_MODE_CONNECTOR_WRITEBACK);
+}
+
+bool dpu_encoder_is_primary(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc;
+
+   if (!drm_enc)
+   return false;
+
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+   return((dpu_enc->disp_info.connector_type == DRM_MODE_CONNECTOR_DSI) ||
+   (dpu_enc->disp_info.connector_type == DRM_MODE_CONNECTOR_eDP));


Why do you need a separate is_primary?


+}
  
  bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc)

  {
@@ -2412,7 +2446,7 @@ int dpu_encoder_setup(struct drm_device *dev, struct 
drm_encoder *enc,
struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
struct drm_encoder *drm_enc = NULL;
struct dpu_encoder_virt *dpu_enc = NULL;
-   int ret = 0;
+   int ret = 0, intf_i;
  
  	dpu_enc = to_dpu_encoder_virt(enc);
  
@@ -2424,13 +2458,17 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,

timer_setup(_enc->frame_done_timer,
dpu_encoder_frame_done_timeout, 0);
  
+	intf_i = disp_info->h_tile_instance[0];

if (disp_info->intf_type == DRM_MODE_ENCODER_DSI)
timer_setup(_enc->vsync_event_timer,
dpu_encoder_vsync_event_handler,
0);
-   else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
+   else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS) {
dpu_enc->wide_bus_en = msm_dp_wide_bus_available(
-   priv->dp[disp_info->h_tile_instance[0]]);
+   priv->dp[intf_i]);
+   disp_info->connector_type =
+   msm_dp_get_connector_type(priv->dp[intf_i]);
+   }
  
  	INIT_DELAYED_WORK(_enc->delayed_off_work,

dpu_encoder_off_work);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index 9e7236e..d361c5d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -25,16 +25,18 @@
   * @num_of_h_tiles: Number of horizontal tiles in case of split interface
   * @h_tile_instance:Controller instance used per tile. Number of elements 
is
   *  based on num_of_h_tiles
- * @is_cmd_modeBoolean to indicate if the CMD mode is requested
+ * @is_cmd_mode:Boolean to indicate if the CMD mode is requested


Unrelated change. If you want to fix a whitespace, please do so. In a 
separate patch.



+ * @connector_type: DRM_MODE_CONNECTOR_ type


You can get this kind of information from the atomic state.
See the for_each_connector_on_encoder


   * @is_te_using_watchdog_timer:  Boolean to indicate watchdog TE is
- *  used instead of panel TE in cmd mode panels
- * @dsc:   DSC configuration data for DSC-enabled displays
+ *  used instead of panel TE in cmd mode panels
+ * 

Re: [v1] drm/msm/disp/dpu1: pin 1 crtc to 1 encoder

2022-11-11 Thread Dmitry Baryshkov

On 11/11/2022 16:56, Kalyan Thota wrote:

Pin each crtc with one encoder. This arrangement will
disallow crtc switching between encoders and also will
facilitate to advertise certain features on crtc based
on encoder type.

Changes in v1:
- use drm_for_each_encoder macro while iterating through
   encoder list (Dmitry)


BTW: if these patches form a series, please send them so.



Signed-off-by: Kalyan Thota 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 21 +++--
  1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 7a5fabc..0d94eec0d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -798,19 +798,20 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
max_crtc_count = min(max_crtc_count, primary_planes_idx);
  
  	/* Create one CRTC per encoder */

-   for (i = 0; i < max_crtc_count; i++) {
-   crtc = dpu_crtc_init(dev, primary_planes[i], cursor_planes[i]);
-   if (IS_ERR(crtc)) {
-   ret = PTR_ERR(crtc);
-   return ret;
+   i = 0;
+   drm_for_each_encoder(encoder, dev) {
+   if (i < max_crtc_count) {


What if max_crtc_counter < num_encoders? I think we should disallow such 
configuration. Can it happen on any of relevant platforms?



+   crtc = dpu_crtc_init(dev, primary_planes[i], 
cursor_planes[i]);
+   if (IS_ERR(crtc)) {
+   ret = PTR_ERR(crtc);
+   return ret;
+   }
+   priv->crtcs[priv->num_crtcs++] = crtc;
+   encoder->possible_crtcs = 1 << drm_crtc_index(crtc);
}
-   priv->crtcs[priv->num_crtcs++] = crtc;
+   i++;
}
  
-	/* All CRTCs are compatible with all encoders */

-   drm_for_each_encoder(encoder, dev)
-   encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
-
return 0;
  }
  


--
With best wishes
Dmitry



Re: [PATCH 2/2] adreno: Detect shutdown during get_param()

2022-11-11 Thread Joel Fernandes
On Fri, Nov 11, 2022 at 4:37 PM Joel Fernandes 
wrote:

>
>
> > On Nov 11, 2022, at 4:28 PM, Akhil P Oommen 
> wrote:
> >
> > On 11/12/2022 1:19 AM, Joel Fernandes (Google) wrote:
> >> Even though the GPU is shut down, during kexec reboot we can have
> userspace
> >> still running. This is especially true if KEXEC_JUMP is not enabled,
> because we
> >> do not freeze userspace in this case.
> >>
> >> To prevent crashes, track that the GPU is shutdown and prevent
> get_param() from
> >> accessing GPU resources if we find it shutdown.
> >>
> >> This fixes the following crash during kexec reboot on an ARM64 device
> with adreno GPU:
> >>
> >> [  292.534314] Kernel panic - not syncing: Asynchronous SError Interrupt
> >> [  292.534323] Hardware name: Google Lazor (rev3 - 8) with LTE (DT)
> >> [  292.534326] Call trace:
> >> [  292.534328]  dump_backtrace+0x0/0x1d4
> >> [  292.534337]  show_stack+0x20/0x2c
> >> [  292.534342]  dump_stack_lvl+0x60/0x78
> >> [  292.534347]  dump_stack+0x18/0x38
> >> [  292.534352]  panic+0x148/0x3b0
> >> [  292.534357]  nmi_panic+0x80/0x94
> >> [  292.534364]  arm64_serror_panic+0x70/0x7c
> >> [  292.534369]  do_serror+0x0/0x7c
> >> [  292.534372]  do_serror+0x54/0x7c
> >> [  292.534377]  el1h_64_error_handler+0x34/0x4c
> >> [  292.534381]  el1h_64_error+0x7c/0x80
> >> [  292.534386]  el1_interrupt+0x20/0x58
> >> [  292.534389]  el1h_64_irq_handler+0x18/0x24
> >> [  292.534395]  el1h_64_irq+0x7c/0x80
> >> [  292.534399]  local_daif_inherit+0x10/0x18
> >> [  292.534405]  el1h_64_sync_handler+0x48/0xb4
> >> [  292.534410]  el1h_64_sync+0x7c/0x80
> >> [  292.534414]  a6xx_gmu_set_oob+0xbc/0x1fc
> >> [  292.534422]  a6xx_get_timestamp+0x40/0xb4
> >> [  292.534426]  adreno_get_param+0x12c/0x1e0
> >> [  292.534433]  msm_ioctl_get_param+0x64/0x70
> >> [  292.534440]  drm_ioctl_kernel+0xe8/0x158
> >> [  292.534448]  drm_ioctl+0x208/0x320
> >> [  292.534453]  __arm64_sys_ioctl+0x98/0xd0
> >> [  292.534461]  invoke_syscall+0x4c/0x118
> >> [  292.534467]  el0_svc_common+0x98/0x104
> >> [  292.534473]  do_el0_svc+0x30/0x80
> >> [  292.534478]  el0_svc+0x20/0x50
> >> [  292.534481]  el0t_64_sync_handler+0x78/0x108
> >> [  292.534485]  el0t_64_sync+0x1a4/0x1a8
> >> [  292.534632] Kernel Offset: 0x1a5f80 from 0xffc00800
> >> [  292.534635] PHYS_OFFSET: 0x8000
> >> [  292.534638] CPU features: 0x40018541,a3300e42
> >> [  292.534644] Memory Limit: none
> >>
> >> Cc: Rob Clark 
> >> Cc: Steven Rostedt 
> >> Cc: Ricardo Ribalda 
> >> Cc: Ross Zwisler 
> >> Signed-off-by: Joel Fernandes (Google) 
> >> ---
> >>  drivers/gpu/drm/msm/adreno/adreno_device.c | 1 +
> >>  drivers/gpu/drm/msm/adreno/adreno_gpu.c| 2 +-
> >>  drivers/gpu/drm/msm/msm_gpu.h  | 3 +++
> >>  3 files changed, 5 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c
> b/drivers/gpu/drm/msm/adreno/adreno_device.c
> >> index f0cff62812c3..03d912dc0130 100644
> >> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
> >> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
> >> @@ -612,6 +612,7 @@ static void adreno_shutdown(struct platform_device
> *pdev)
> >>  {
> >>  struct msm_gpu *gpu = dev_to_gpu(>dev);
> >>  +gpu->is_shutdown = true;
> >>  WARN_ON_ONCE(adreno_system_suspend(>dev));
> >>  }
> >>  diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> >> index 382fb7f9e497..6903c6892469 100644
> >> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> >> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> >> @@ -251,7 +251,7 @@ int adreno_get_param(struct msm_gpu *gpu, struct
> msm_file_private *ctx,
> >>  struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
> >>/* No pointer params yet */
> >> -if (*len != 0)
> >> +if (*len != 0 || gpu->is_shutdown)
> >>  return -EINVAL;
> > This will race with shutdown.
>
> Could you clarify what you mean? At this point in the code, the shutdown
> is completed and it crashes here.
>


Ok so I think you meant that if the shut down happens after we sample the
is_shutdown, then we run into the same issue.

I can’t reproduce that but I’ll look into that. Another way might be to
synchronize using a mutex. Though maybe the shutdown path can wait for
active pm_runtime references?

Thanks.




> > Probably, propagating back the return value of pm_runtime_get() in every
> possible ioctl call path is the right thing to do.
>
> Ok I’ll look into that. But the patch I posted works reliably and fixes
> all crashes we could reproduce.
>
> > I have never thought about this scenario. Do you know why userspace is
> not freezed before kexec?
>
> I am not sure. It depends on how kexec is used. The userspace freeze
> happens only when kexec is called to switch back and forth between
> different kernels (persistence mode). In such scenario I believe the
> userspace has to be frozen and unfrozen. However for normal kexec, that
> does not happen.
>
> Thanks.
>
>
> >
> > -Akhil.
> >>  

[PATCH 2/7] drm_print: fixup improve stale comment

2022-11-11 Thread Jim Cromie
Cited commit uses stale macro name, fix this.  And improve the explanation.

When DRM_USE_DYNAMIC_DEBUG=y, DECLARE_DYNDBG_CLASSMAP() does the
mapping of DRM_UT_* onto BITs in drm.debug.  While this is still using
the drm_debug_category enum to do the mapping, its doing so somewhat
indirectly, with the ordered set of DRM_UT_* enum-vals.  This requires
that the macro args: DRM_UT_* list must be kept in sync.

fixes: f158936b60a7 (drm: POC drm on dyndbg - use in core, 2 helpers, 3 
drivers.)
Signed-off-by: Jim Cromie 
---
. emphasize ABI non-change despite enum val change - Jani
---
 include/drm/drm_print.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index a44fb7ef257f..06deb58d5af4 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -276,7 +276,10 @@ static inline struct drm_printer drm_err_printer(const 
char *prefix)
  *
  */
 enum drm_debug_category {
-   /* These names must match those in DYNAMIC_DEBUG_CLASSBITS */
+   /*
+* Keep DECLARE_DYNDBG_CLASSMAP args in sync with changes
+* here, the values define BIT()s in drm.debug, so are ABI.
+*/
/**
 * @DRM_UT_CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c,
 * drm_memory.c, ...
-- 
2.38.1



[PATCH 7/7] dyndbg: replace classmap list with a vector

2022-11-11 Thread Jim Cromie
Classmaps are stored/linked in a section/array, but are each added to
the module's ddebug_table.maps list-head.

This is unnecessary; even when ddebug_attach_classmap() is handling
the builtin section (with classmaps for multiple builtin modules), its
contents are ordered, so a module's possibly multiple classmaps will
be consecutive in the section, and could be treated as a vector/block,
since both start-addy and subrange length are in the ddebug_info arg.

So this changes:

struct ddebug_table gets: classes for the start-addy, num_classes for
the length (placed to improve struct packing).

The loading: in ddebug_attach_module_classes(), replace the
for-the-modname list-add loop, with a forloop that finds the module's
subrange (start,length) of matching classmaps within the possibly
builtin classmaps vector, and saves those to the ddebug_table.

The reading/using: change list-foreach loops in ddebug_class_name() &
ddebug_find_valid_class() to walk the array from start to length.

Also move #define __outvar up, above an added use in a fn-prototype.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 61 -
 1 file changed, 32 insertions(+), 29 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 48ca1387a409..fd5296dbb40f 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -45,10 +45,11 @@ extern struct ddebug_class_map __start___dyndbg_classes[];
 extern struct ddebug_class_map __stop___dyndbg_classes[];
 
 struct ddebug_table {
-   struct list_head link, maps;
+   struct list_head link;
const char *mod_name;
-   unsigned int num_ddebugs;
struct _ddebug *ddebugs;
+   struct ddebug_class_map *classes;
+   unsigned int num_ddebugs, num_classes;
 };
 
 struct ddebug_query {
@@ -146,13 +147,15 @@ static void vpr_info_dq(const struct ddebug_query *query, 
const char *msg)
  query->first_lineno, query->last_lineno, query->class_string);
 }
 
+#define __outvar /* filled by callee */
 static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table 
const *dt,
- const char 
*class_string, int *class_id)
+   const char 
*class_string,
+   __outvar int *class_id)
 {
struct ddebug_class_map *map;
-   int idx;
+   int i, idx;
 
-   list_for_each_entry(map, >maps, link) {
+   for (map = dt->classes, i = 0; i < dt->num_classes; i++, map++) {
idx = match_string(map->class_names, map->length, class_string);
if (idx >= 0) {
*class_id = idx + map->base;
@@ -163,7 +166,6 @@ static struct ddebug_class_map 
*ddebug_find_valid_class(struct ddebug_table cons
return NULL;
 }
 
-#define __outvar /* filled by callee */
 /*
  * Search the tables for _ddebug's which match the given `query' and
  * apply the `flags' and `mask' to them.  Returns number of matching
@@ -1109,9 +,10 @@ static void *ddebug_proc_next(struct seq_file *m, void 
*p, loff_t *pos)
 
 static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug 
*dp)
 {
-   struct ddebug_class_map *map;
+   struct ddebug_class_map *map = iter->table->classes;
+   int i, nc = iter->table->num_classes;
 
-   list_for_each_entry(map, >table->maps, link)
+   for (i = 0; i < nc; i++, map++)
if (class_in_range(dp->class_id, map))
return map->class_names[dp->class_id - map->base];
 
@@ -1195,30 +1198,31 @@ static const struct proc_ops proc_fops = {
.proc_write = ddebug_proc_write
 };
 
-static void ddebug_attach_module_classes(struct ddebug_table *dt,
-struct ddebug_class_map *classes,
-int num_classes)
+static void ddebug_attach_module_classes(struct ddebug_table *dt, struct 
_ddebug_info *di)
 {
struct ddebug_class_map *cm;
-   int i, j, ct = 0;
+   int i, nc = 0;
 
-   for (cm = classes, i = 0; i < num_classes; i++, cm++) {
+   /*
+* Find this module's classmaps in a subrange/wholerange of
+* the builtin/modular classmap vector/section.  Save the start
+* and length of the subrange at its edges.
+*/
+   for (cm = di->classes, i = 0; i < di->num_classes; i++, cm++) {
 
if (!strcmp(cm->mod_name, dt->mod_name)) {
-
-   v2pr_info("class[%d]: module:%s base:%d len:%d 
ty:%d\n", i,
- cm->mod_name, cm->base, cm->length, 
cm->map_type);
-
-   for (j = 0; j < cm->length; j++)
-   v3pr_info(" %d: %d %s\n", j + cm->base, j,
- cm->class_names[j]);
-
-   list_add(>link, >maps);
-   ct++;
+ 

[PATCH 3/7] test-dyndbg: fixup CLASSMAP usage error

2022-11-11 Thread Jim Cromie
more careful reading of test output reveals:

lib/test_dynamic_debug.c:103 [test_dynamic_debug]do_cats =pmf "doing 
categories\n"
lib/test_dynamic_debug.c:105 [test_dynamic_debug]do_cats =p "LOW msg\n" 
class:MID
lib/test_dynamic_debug.c:106 [test_dynamic_debug]do_cats =p "MID msg\n" class:HI
lib/test_dynamic_debug.c:107 [test_dynamic_debug]do_cats =_ "HI msg\n" class 
unknown, _id:13

That last line is wrong, the HI class is declared.

But the enum's 1st val (explicitly initialized) was wrong; it must be
_base, not _base+1 (a DECLARE_DYNDBG_CLASSMAP param).  So the last
enumeration exceeded the range of mapped class-id's, which triggered
the "class unknown" report.  Basically, I coded in an error, and
forgot to verify it and remove it.

RFC:

This patch fixes a bad usage of DEFINE_DYNDBG_CLASSMAP(), showing that
it is too error-prone.  As noted in test-dynamic-debug.c comments:

 * Using the CLASSMAP api:
 * - classmaps must have corresponding enum
 * - enum symbols must match/correlate with class-name strings in the map.
 * - base must equal enum's 1st value
 * - multiple maps must set their base to share the 0-62 class_id space !!
 *   (build-bug-on tips welcome)

Those shortcomings could largely be fixed with a __stringify_list
(which doesn't exist) used in DEFINE_DYNAMIC_DEBUG_CLASSMAP(), on
__VA_ARGS__ a 2nd time.  Then, DRM would pass DRM_UT_* ; all the
categories, in order, and not their stringifications, which created
all the usage complications above.

Signed-off-by: Jim Cromie 
---
 lib/test_dynamic_debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index 8dd250ad022b..a01f0193a419 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -75,7 +75,7 @@ DD_SYS_WRAP(disjoint_bits, p);
 DD_SYS_WRAP(disjoint_bits, T);
 
 /* symbolic input, independent bits */
-enum cat_disjoint_names { LOW = 11, MID, HI };
+enum cat_disjoint_names { LOW = 10, MID, HI };
 DECLARE_DYNDBG_CLASSMAP(map_disjoint_names, DD_CLASS_TYPE_DISJOINT_NAMES, 10,
"LOW", "MID", "HI");
 DD_SYS_WRAP(disjoint_names, p);
-- 
2.38.1



[PATCH 6/7] dyndbg: clone DECLARE_DYNDBG_CLASSMAP to REFERENCE_DYNDBG_CLASSMAP

2022-11-11 Thread Jim Cromie
DECLARE_DYNDBG_CLASSMAPs job is to allow modules to declare the debug
classes/categories they want dyndbg to >control.  Its args name the
class-names, and the sysfs interface style (usually a class-bitmap).
A separate module_param_cb wires the sysfs node to the classmap.

In DRM, multiple modules declare identical DRM_UT_* classmaps, so that
they are modified across those modules in a coordinated way, by either
explicit class DRM_UT_* queries to >control, or by writes to drm.debug
(/sys/module/drm/parameters/debug).

This coordination-by-identical-declarations is weird, so this patch
splits the macro into DECLARE and REFERENCE (USE?) flavors.  This
distinction improves the api; DECLARE is used once to specify the
classmap, and multiple users REFERENCE the single declaration
explicitly.

Currently the latter just reuses the former, and still needs all the
same args, but that can be tuned later; the DECLARE can initialize the
(extern/global) struct classmap, and REFERENCE can, well reference
that struct.

Signed-off-by: Jim Cromie 
---
RFC: s/REFERENCE_/USE_/ ??
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  2 +-
 drivers/gpu/drm/display/drm_dp_helper.c |  2 +-
 drivers/gpu/drm/drm_crtc_helper.c   |  2 +-
 drivers/gpu/drm/i915/i915_params.c  |  2 +-
 drivers/gpu/drm/nouveau/nouveau_drm.c   |  2 +-
 include/linux/dynamic_debug.h   | 10 ++
 6 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 3c9fecdd6b2f..5c733d96fe4c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -188,7 +188,7 @@ int amdgpu_vcnfw_log;
 
 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
 
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
+REFERENCE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_CORE",
"DRM_UT_DRIVER",
"DRM_UT_KMS",
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 16565a0a5da6..1f20c1e721a4 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -41,7 +41,7 @@
 
 #include "drm_dp_helper_internal.h"
 
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
+REFERENCE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_CORE",
"DRM_UT_DRIVER",
"DRM_UT_KMS",
diff --git a/drivers/gpu/drm/drm_crtc_helper.c 
b/drivers/gpu/drm/drm_crtc_helper.c
index 7d86020b5244..4675c95c90b4 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -51,7 +51,7 @@
 
 #include "drm_crtc_helper_internal.h"
 
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
+REFERENCE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_CORE",
"DRM_UT_DRIVER",
"DRM_UT_KMS",
diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index d1e4d528cb17..14ebbbf53821 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -29,7 +29,7 @@
 #include "i915_params.h"
 #include "i915_drv.h"
 
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
+REFERENCE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_CORE",
"DRM_UT_DRIVER",
"DRM_UT_KMS",
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c 
b/drivers/gpu/drm/nouveau/nouveau_drm.c
index fd99ec0f4257..b943bf2a36fe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -71,7 +71,7 @@
 #include "nouveau_svm.h"
 #include "nouveau_dmem.h"
 
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
+REFERENCE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_CORE",
"DRM_UT_DRIVER",
"DRM_UT_KMS",
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 41682278d2e8..76430bac7f79 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -111,6 +111,16 @@ struct ddebug_class_map {
 #define NUM_TYPE_ARGS(eltype, ...) \
 (sizeof((eltype[]){__VA_ARGS__}) / sizeof(eltype))
 
+/*
+ * refer to the classmap instantiated once, by the macro above.  This
+ * distinguishes the multiple users of drm.debug from the single
+ * definition, allowing them to specialize.  ATM its a pass-thru, but
+ * it should help regularize the admittedly wierd sharing by identical
+ * definitions.
+ */
+#define REFERENCE_DYNDBG_CLASSMAP(_var, _maptype, _base, 

[PATCH 5/7] dyndbg: fix readback value on LEVEL_NAMES interfaces

2022-11-11 Thread Jim Cromie
Since sysfs knobs should generally read-back what was just written
(unless theres a good reason to do otherwise), this result (using
test_dynamic_debug.ko) is suboptimal:

  echo L3 > p_level_names
  cat p_level_names
  4

Fix this with a -1 offset in LEVEL_NAMES readback.

NOTE:

Calling this a BUG is debatable, and the above is slightly inaccurate
wrt "read-back"; whats written is a LEVEL_NAME (a string).  Whats read
back is an integer, giving the 'edge' of the 'low-pass-filter'

The actual test looks like:

RTT: L4 -> p_level_names : 4 :: DOING: levels 4-1
[   17.509594] dyndbg: "L4" > p_level_names:0x4
[   17.510115] dyndbg: apply: 0x1f to: 0xf
[   17.510506] dyndbg: query 0: "class L4 +p" mod:*
[   17.510992] dyndbg: split into words: "class" "L4" "+p"
[   17.511521] dyndbg: op='+'
[   17.511811] dyndbg: flags=0x1
[   17.512127] dyndbg: *flagsp=0x1 *maskp=0x
[   17.512604] dyndbg: parsed: func="" file="" module="" format="" lineno=0-0 
class=L4
[   17.513414] dyndbg: applied: func="" file="" module="" format="" lineno=0-0 
class=L4
[   17.514204] dyndbg: processed 1 queries, with 1 matches, 0 errs
[   17.514809] dyndbg: bit_4: 1 matches on class: L4 -> 0x1f
[   17.515355] dyndbg: p_level_names: changed bit-4: "L4" f->1f
[   17.515933] dyndbg: total matches: 1
crap [[ 5 != 4 ]]

This -1 adjustment just reports the edge consistently with its
input-mapping.

Fixes: b9400852c080 (dyndbg: add drm.debug style (drm/parameters/debug) bitmap 
support)

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 009f2ead09c1..48ca1387a409 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -794,6 +794,8 @@ int param_get_dyndbg_classes(char *buffer, const struct 
kernel_param *kp)
return scnprintf(buffer, PAGE_SIZE, "0x%lx\n", *dcp->bits);
 
case DD_CLASS_TYPE_LEVEL_NAMES:
+   return scnprintf(buffer, PAGE_SIZE, "%d\n", *dcp->lvl - 1);
+
case DD_CLASS_TYPE_LEVEL_NUM:
return scnprintf(buffer, PAGE_SIZE, "%d\n", *dcp->lvl);
default:
-- 
2.38.1



[PATCH 4/7] test-dyndbg: show that DEBUG enables prdbgs at compiletime

2022-11-11 Thread Jim Cromie
Dyndbg is required to enable prdbgs at compile-time if DEBUG is
defined.  Show this works; add the defn to test_dynamic_debug.c,
and manually inspect/verify its effect at module load:

[   15.292810] dyndbg: module:test_dynamic_debug attached 4 classes
[   15.293189] dyndbg:  32 debug prints in module test_dynamic_debug
[   15.293715] test_dd: init start
[   15.293716] test_dd: doing categories
[   15.293716] test_dd: LOW msg
...
[   15.293733] test_dd: L6 msg
[   15.293733] test_dd: L7 msg
[   15.293733] test_dd: init done

NOTES:

As is observable above, define DEBUG enables all prdbgs, including
those in mod_init-fn, and more notably, the "class"d ones (callsites
with non-default class_ids).

This differs from the >control interface, which in order to properly
protect a client's class'd prdbgs, requires a "class FOO" in queries
to change them.  Note that the DEBUG is in the module source file.

This yields an occaisional surprise; the following disables all the
compile-time enabled plain prdbgs, but leaves the class'd ones
enabled.

 :#> modprobe test_dynamic_debug dyndbg==_

Signed-off-by: Jim Cromie 
---
 lib/test_dynamic_debug.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index a01f0193a419..9d48689dc0ab 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -8,6 +8,8 @@
 
 #define pr_fmt(fmt) "test_dd: " fmt
 
+#define DEBUG
+
 #include 
 
 /* run tests by reading or writing sysfs node: do_prints */
-- 
2.38.1



[PATCH 1/7] drm: mark drm.debug-on-dyndbg as BROKEN for now

2022-11-11 Thread Jim Cromie
drm.debug-on-dyndbg has a regression, due to a chicken-egg
initialization problem:

1- modprobe i915
   i915 needs drm.ko, which is loaded 1st

2- "modprobe drm drm.debug=0x1ff" (virtual/implied)
   drm.debug is set post-initialization, from boot-args etc

3- `modprobe i915` finishes

W/O drm.debug-on-dyndbg that just works, because all drm_dbg*
callsites use drm_debug_enabled() to check __drm_debug & DEM_UT_
before printing.

But the whole point of drm.debug-on-dyndbg is to avoid that runtime
test, by enabling (at post-modinit) a static-key at each callsite in
the just-loaded module.

And since drm.ko is loaded before all dependent modules, none are
"just-loaded", and no drm.debug callsites are present yet, except
those in drm.ko itself.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 34f5a092c99e..0d1e59e6bb7e 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -54,6 +54,7 @@ config DRM_DEBUG_MM
 config DRM_USE_DYNAMIC_DEBUG
bool "use dynamic debug to implement drm.debug"
default y
+   depends on BROKEN   # chicken-egg initial enable problem
depends on DRM
depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
depends on JUMP_LABEL
-- 
2.38.1



[PATCH 0/7] DYNAMIC_DEBUG fixups for rc

2022-11-11 Thread Jim Cromie
hi Jason, Greg, DRM-folk,

drm.debug-on-dyndbg has a regression due to a chicken-&-egg problem;
drm.debug is applied to enable dyndbg callsites before the dependent
modules' callsites are available to be enabled.

My "fixes" are unready, so lets just mark it BROKEN for now.

Meanwhile, heres some other fixes, a comment tweak, a proof of
non-bug, an internal simplification, and a cleanup/improvement to the
main macro (API):

Split DECLARE_DYNDBG_CLASSMAP in 1/2; REFERENCE_DYNDBG_CLASSMAP now
refers to a classmap DECLARE'd just once.  I think this gives a path
away from the coordination-by-identical-classmaps "feature" that Jani
and others thought was "weird" (my term).


Jim Cromie (7):
  drm: mark drm.debug-on-dyndbg as BROKEN for now
  drm_print: fixup improve stale comment
  test-dyndbg: fixup CLASSMAP usage error
  test-dyndbg: show that DEBUG enables prdbgs at compiletime
  dyndbg: fix readback value on LEVEL_NAMES interfaces
  dyndbg: clone DECLARE_DYNDBG_CLASSMAP to REFERENCE_DYNDBG_CLASSMAP
  dyndbg: replace classmap list with a vector

 drivers/gpu/drm/Kconfig |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  2 +-
 drivers/gpu/drm/display/drm_dp_helper.c |  2 +-
 drivers/gpu/drm/drm_crtc_helper.c   |  2 +-
 drivers/gpu/drm/i915/i915_params.c  |  2 +-
 drivers/gpu/drm/nouveau/nouveau_drm.c   |  2 +-
 include/drm/drm_print.h |  5 +-
 include/linux/dynamic_debug.h   | 10 
 lib/dynamic_debug.c | 63 +
 lib/test_dynamic_debug.c|  4 +-
 10 files changed, 57 insertions(+), 36 deletions(-)

-- 
2.38.1



Re: [v9] drm/msm/disp/dpu1: add support for dspp sub block flush in sc7280

2022-11-11 Thread Dmitry Baryshkov

On 11/11/2022 16:55, Kalyan Thota wrote:

Flush mechanism for DSPP blocks has changed in sc7280 family, it
allows individual sub blocks to be flushed in coordination with
master flush control.

Representation: master_flush && (PCC_flush | IGC_flush .. etc )

This change adds necessary support for the above design.

Changes in v1:
- Few nits (Doug, Dmitry)
- Restrict sub-block flush programming to dpu_hw_ctl file (Dmitry)

Changes in v2:
- Move the address offset to flush macro (Dmitry)
- Seperate ops for the sub block flush (Dmitry)

Changes in v3:
- Reuse the DPU_DSPP_xx enum instead of a new one (Dmitry)

Changes in v4:
- Use shorter version for unsigned int (Stephen)

Changes in v5:
- Spurious patch please ignore.

Changes in v6:
- Add SOB tag (Doug, Dmitry)

Changes in v7:
- Cache flush mask per dspp (Dmitry)
- Few nits (Marijn)

Changes in v8:
- Few nits (Marijn)

Changes in v9:
- use DSPP enum while accessing flush mask to make it readable (Dmitry)
- Few nits (Dmitry)

Signed-off-by: Kalyan Thota 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   |  2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  5 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  4 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 64 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h |  5 +-
  5 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 601d687..4170fbe 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -766,7 +766,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
  
  		/* stage config flush mask */

ctl->ops.update_pending_flush_dspp(ctl,
-   mixer[i].hw_dspp->idx);
+   mixer[i].hw_dspp->idx, DPU_DSPP_PCC);
}
  }
  
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c

index 27f029f..0eecb2f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -65,7 +65,10 @@
(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
  
  #define CTL_SC7280_MASK \

-   (BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | 
BIT(DPU_CTL_VM_CFG))
+   (BIT(DPU_CTL_ACTIVE_CFG) | \
+BIT(DPU_CTL_FETCH_ACTIVE) | \
+BIT(DPU_CTL_VM_CFG) | \
+BIT(DPU_CTL_DSPP_SUB_BLOCK_FLUSH))
  
  #define MERGE_3D_SM8150_MASK (0)
  
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h

index 38aa38a..126ee37 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -161,10 +161,12 @@ enum {
   * DSPP sub-blocks
   * @DPU_DSPP_PCC Panel color correction block
   * @DPU_DSPP_GC  Gamma correction block
+ * @DPU_DSPP_IGC Inverse gamma correction block
   */
  enum {
DPU_DSPP_PCC = 0x1,
DPU_DSPP_GC,
+   DPU_DSPP_IGC,
DPU_DSPP_MAX
  };
  
@@ -191,6 +193,7 @@ enum {

   * @DPU_CTL_SPLIT_DISPLAY:CTL supports video mode split display
   * @DPU_CTL_FETCH_ACTIVE: Active CTL for fetch HW (SSPPs)
   * @DPU_CTL_VM_CFG:   CTL config to support multiple VMs
+ * @DPU_CTL_DSPP_BLOCK_FLUSH  CTL config to support dspp sub-block flush
   * @DPU_CTL_MAX
   */
  enum {
@@ -198,6 +201,7 @@ enum {
DPU_CTL_ACTIVE_CFG,
DPU_CTL_FETCH_ACTIVE,
DPU_CTL_VM_CFG,
+   DPU_CTL_DSPP_SUB_BLOCK_FLUSH,
DPU_CTL_MAX
  };
  
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c

index a35ecb6..0ee8220 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -28,22 +28,23 @@
  #define   CTL_INTF_ACTIVE   0x0F4
  #define   CTL_MERGE_3D_FLUSH0x100
  #define   CTL_DSC_ACTIVE0x0E8
-#define   CTL_DSC_FLUSH0x104
+#define   CTL_DSC_FLUSH 0x104
  #define   CTL_WB_FLUSH  0x108
  #define   CTL_INTF_FLUSH0x110
  #define   CTL_INTF_MASTER   0x134
  #define   CTL_FETCH_PIPE_ACTIVE 0x0FC
+#define   CTL_DSPP_n_FLUSH(n)   ((0x13C) + ((n) * 4))
  
-#define CTL_MIXER_BORDER_OUTBIT(24)

-#define CTL_FLUSH_MASK_CTL  BIT(17)
+#define   CTL_MIXER_BORDER_OUT  BIT(24)
+#define   CTL_FLUSH_MASK_CTLBIT(17)


Whitespace changes should go to a separate patch. And I'd prefer to have 
extra whitespaces removed, not added.


Other than that LGTM now.

  
-#define DPU_REG_RESET_TIMEOUT_US2000

-#define  MERGE_3D_IDX   23
-#define  DSC_IDX22
-#define  INTF_IDX   31
-#define WB_IDX  16
-#define CTL_INVALID_BIT 0x
-#define CTL_DEFAULT_GROUP_ID   0xf
+#define   

Re: [RFC PATCH v3 0/3] new subsystem for compute accelerator devices

2022-11-11 Thread Christopher Friedt
Hi Oded,

On Sun, Nov 6, 2022 at 4:03 PM Oded Gabbay  wrote:
> The patches are in the following repo:
> https://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/accel.git/log/?h=accel_v3
>
> As in v2, The HEAD of that branch is a commit adding a dummy driver that
> registers an accel device using the new framework. This can be served
> as a simple reference. I have checked inserting and removing the dummy driver,
> and opening and closing /dev/accel/accel0 and nothing got broken :)
>
> v1 cover letter:
> https://lkml.org/lkml/2022/10/22/544
>
> v2 cover letter:
> https://lore.kernel.org/lkml/20221102203405.1797491-1-ogab...@kernel.org/T/

I was in the room at Plumbers when a lot of this was discussed (in
2022 and also 2019), but I haven't really had an opportunity to
provide feedback until now. In general, I think it's great and thanks
for pushing it forward and getting feedback.

The v1 cover letter mentioned RAS (reliability, availability,
serviceability) and Dave also mentioned it here [1]. There was a
suggestion to use Netlink. It's an area that I'm fairly interested in
because I do a lot of development on the firmware side (and
specifically, with Zephyr).

Personally, I think Netlink could be one option for serializing and
deserializing RAS information but it would be helpful for that
interface to be somewhat flexible, like a void * and length, and to
provide userspace the capability of querying which RAS formats are
supported.

For example, AntMicro used OpenAMP + rpmsg in their NVMe accelerator,
and gave a talk on it at ZDS and Plumbers this year [2][3].

In Zephyr, the LGPL license for Netlink might be a non-starter
(although I'm no lawyer). However, Zephyr does already support
OpenAMP, protobufs, json, and will soon support Thrift.

Some companies might prefer to use Netlink. Others might prefer to use
ASN.1. Some companies might prefer to use key-value pairs and limit
the parameters and messages to uint32s. Some might handle all of the
RAS details in-kernel, while others might want the kernel to act more
like a transport to firmware.

Companies already producing accelerators may have a particular
preference for serialization / deserialization in their own
datacenters.

With that, it would be helpful to be able to query RAS capabilities via ioctl.

#define ACCEL_CAP_RAS_KEY_VAL_32 BIT(0)
#define ACCEL_CAP_RAS_NETLINK BIT(1)
#define ACCEL_CAP_RAS_JSON BIT(2)
#define ACCEL_CAP_RAS_PROTOBUF BIT(3)
#define ACCEL_CAP_RAS_GRPC BIT(4)
#define ACCEL_CAP_RAS_THRIFT BIT(5)
#define ACCEL_CAP_RAS_JSON BIT(6)
#define ACCEL_CAP_RAS_ASN1 BIT(7)

or something along those lines. Anyway, just putting the idea out there.

I'm sure there are a lot of opinions on this topic and that there are
a lot of implications of using this or that serialization format.
Obviously there can be security implications as well.

Apologies if I've already missed some of this discussion.

Cheers,

C

[1] https://airlied.blogspot.com/2022/09/accelerators-bof-outcomes-summary.html
[2] 
https://zephyr2022.sched.com/event/10CFD/open-source-nvme-ai-accelerator-platform-with-zephyr-karol-gugala-antmicro
[3] https://lpc.events/event/16/contributions/1245/


Re: [PATCH 2/2] adreno: Detect shutdown during get_param()

2022-11-11 Thread Joel Fernandes



> On Nov 11, 2022, at 4:28 PM, Akhil P Oommen  wrote:
> 
> On 11/12/2022 1:19 AM, Joel Fernandes (Google) wrote:
>> Even though the GPU is shut down, during kexec reboot we can have userspace
>> still running. This is especially true if KEXEC_JUMP is not enabled, because 
>> we
>> do not freeze userspace in this case.
>> 
>> To prevent crashes, track that the GPU is shutdown and prevent get_param() 
>> from
>> accessing GPU resources if we find it shutdown.
>> 
>> This fixes the following crash during kexec reboot on an ARM64 device with 
>> adreno GPU:
>> 
>> [  292.534314] Kernel panic - not syncing: Asynchronous SError Interrupt
>> [  292.534323] Hardware name: Google Lazor (rev3 - 8) with LTE (DT)
>> [  292.534326] Call trace:
>> [  292.534328]  dump_backtrace+0x0/0x1d4
>> [  292.534337]  show_stack+0x20/0x2c
>> [  292.534342]  dump_stack_lvl+0x60/0x78
>> [  292.534347]  dump_stack+0x18/0x38
>> [  292.534352]  panic+0x148/0x3b0
>> [  292.534357]  nmi_panic+0x80/0x94
>> [  292.534364]  arm64_serror_panic+0x70/0x7c
>> [  292.534369]  do_serror+0x0/0x7c
>> [  292.534372]  do_serror+0x54/0x7c
>> [  292.534377]  el1h_64_error_handler+0x34/0x4c
>> [  292.534381]  el1h_64_error+0x7c/0x80
>> [  292.534386]  el1_interrupt+0x20/0x58
>> [  292.534389]  el1h_64_irq_handler+0x18/0x24
>> [  292.534395]  el1h_64_irq+0x7c/0x80
>> [  292.534399]  local_daif_inherit+0x10/0x18
>> [  292.534405]  el1h_64_sync_handler+0x48/0xb4
>> [  292.534410]  el1h_64_sync+0x7c/0x80
>> [  292.534414]  a6xx_gmu_set_oob+0xbc/0x1fc
>> [  292.534422]  a6xx_get_timestamp+0x40/0xb4
>> [  292.534426]  adreno_get_param+0x12c/0x1e0
>> [  292.534433]  msm_ioctl_get_param+0x64/0x70
>> [  292.534440]  drm_ioctl_kernel+0xe8/0x158
>> [  292.534448]  drm_ioctl+0x208/0x320
>> [  292.534453]  __arm64_sys_ioctl+0x98/0xd0
>> [  292.534461]  invoke_syscall+0x4c/0x118
>> [  292.534467]  el0_svc_common+0x98/0x104
>> [  292.534473]  do_el0_svc+0x30/0x80
>> [  292.534478]  el0_svc+0x20/0x50
>> [  292.534481]  el0t_64_sync_handler+0x78/0x108
>> [  292.534485]  el0t_64_sync+0x1a4/0x1a8
>> [  292.534632] Kernel Offset: 0x1a5f80 from 0xffc00800
>> [  292.534635] PHYS_OFFSET: 0x8000
>> [  292.534638] CPU features: 0x40018541,a3300e42
>> [  292.534644] Memory Limit: none
>> 
>> Cc: Rob Clark 
>> Cc: Steven Rostedt 
>> Cc: Ricardo Ribalda 
>> Cc: Ross Zwisler 
>> Signed-off-by: Joel Fernandes (Google) 
>> ---
>>  drivers/gpu/drm/msm/adreno/adreno_device.c | 1 +
>>  drivers/gpu/drm/msm/adreno/adreno_gpu.c| 2 +-
>>  drivers/gpu/drm/msm/msm_gpu.h  | 3 +++
>>  3 files changed, 5 insertions(+), 1 deletion(-)
>> 
>> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
>> b/drivers/gpu/drm/msm/adreno/adreno_device.c
>> index f0cff62812c3..03d912dc0130 100644
>> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
>> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
>> @@ -612,6 +612,7 @@ static void adreno_shutdown(struct platform_device *pdev)
>>  {
>>  struct msm_gpu *gpu = dev_to_gpu(>dev);
>>  +gpu->is_shutdown = true;
>>  WARN_ON_ONCE(adreno_system_suspend(>dev));
>>  }
>>  diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
>> b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
>> index 382fb7f9e497..6903c6892469 100644
>> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
>> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
>> @@ -251,7 +251,7 @@ int adreno_get_param(struct msm_gpu *gpu, struct 
>> msm_file_private *ctx,
>>  struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
>>/* No pointer params yet */
>> -if (*len != 0)
>> +if (*len != 0 || gpu->is_shutdown)
>>  return -EINVAL;
> This will race with shutdown.

Could you clarify what you mean? At this point in the code, the shutdown is 
completed and it crashes here.

> Probably, propagating back the return value of pm_runtime_get() in every 
> possible ioctl call path is the right thing to do.

Ok I’ll look into that. But the patch I posted works reliably and fixes all 
crashes we could reproduce.

> I have never thought about this scenario. Do you know why userspace is not 
> freezed before kexec?

I am not sure. It depends on how kexec is used. The userspace freeze happens 
only when kexec is called to switch back and forth between different kernels 
(persistence mode). In such scenario I believe the userspace has to be frozen 
and unfrozen. However for normal kexec, that does not happen.

Thanks.


> 
> -Akhil.
>>switch (param) {
>> diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
>> index ff911e7305ce..f18b0a91442b 100644
>> --- a/drivers/gpu/drm/msm/msm_gpu.h
>> +++ b/drivers/gpu/drm/msm/msm_gpu.h
>> @@ -214,6 +214,9 @@ struct msm_gpu {
>>  /* does gpu need hw_init? */
>>  bool needs_hw_init;
>>  +/* is the GPU shutdown? */
>> +bool is_shutdown;
>> +
>>  /**
>>   * global_faults: number of GPU hangs not attributed to a particular
>>   * address space
> 


Re: [PATCH 2/2] adreno: Detect shutdown during get_param()

2022-11-11 Thread Akhil P Oommen

On 11/12/2022 1:19 AM, Joel Fernandes (Google) wrote:

Even though the GPU is shut down, during kexec reboot we can have userspace
still running. This is especially true if KEXEC_JUMP is not enabled, because we
do not freeze userspace in this case.

To prevent crashes, track that the GPU is shutdown and prevent get_param() from
accessing GPU resources if we find it shutdown.

This fixes the following crash during kexec reboot on an ARM64 device with 
adreno GPU:

[  292.534314] Kernel panic - not syncing: Asynchronous SError Interrupt
[  292.534323] Hardware name: Google Lazor (rev3 - 8) with LTE (DT)
[  292.534326] Call trace:
[  292.534328]  dump_backtrace+0x0/0x1d4
[  292.534337]  show_stack+0x20/0x2c
[  292.534342]  dump_stack_lvl+0x60/0x78
[  292.534347]  dump_stack+0x18/0x38
[  292.534352]  panic+0x148/0x3b0
[  292.534357]  nmi_panic+0x80/0x94
[  292.534364]  arm64_serror_panic+0x70/0x7c
[  292.534369]  do_serror+0x0/0x7c
[  292.534372]  do_serror+0x54/0x7c
[  292.534377]  el1h_64_error_handler+0x34/0x4c
[  292.534381]  el1h_64_error+0x7c/0x80
[  292.534386]  el1_interrupt+0x20/0x58
[  292.534389]  el1h_64_irq_handler+0x18/0x24
[  292.534395]  el1h_64_irq+0x7c/0x80
[  292.534399]  local_daif_inherit+0x10/0x18
[  292.534405]  el1h_64_sync_handler+0x48/0xb4
[  292.534410]  el1h_64_sync+0x7c/0x80
[  292.534414]  a6xx_gmu_set_oob+0xbc/0x1fc
[  292.534422]  a6xx_get_timestamp+0x40/0xb4
[  292.534426]  adreno_get_param+0x12c/0x1e0
[  292.534433]  msm_ioctl_get_param+0x64/0x70
[  292.534440]  drm_ioctl_kernel+0xe8/0x158
[  292.534448]  drm_ioctl+0x208/0x320
[  292.534453]  __arm64_sys_ioctl+0x98/0xd0
[  292.534461]  invoke_syscall+0x4c/0x118
[  292.534467]  el0_svc_common+0x98/0x104
[  292.534473]  do_el0_svc+0x30/0x80
[  292.534478]  el0_svc+0x20/0x50
[  292.534481]  el0t_64_sync_handler+0x78/0x108
[  292.534485]  el0t_64_sync+0x1a4/0x1a8
[  292.534632] Kernel Offset: 0x1a5f80 from 0xffc00800
[  292.534635] PHYS_OFFSET: 0x8000
[  292.534638] CPU features: 0x40018541,a3300e42
[  292.534644] Memory Limit: none

Cc: Rob Clark 
Cc: Steven Rostedt 
Cc: Ricardo Ribalda 
Cc: Ross Zwisler 
Signed-off-by: Joel Fernandes (Google) 
---
  drivers/gpu/drm/msm/adreno/adreno_device.c | 1 +
  drivers/gpu/drm/msm/adreno/adreno_gpu.c| 2 +-
  drivers/gpu/drm/msm/msm_gpu.h  | 3 +++
  3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index f0cff62812c3..03d912dc0130 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -612,6 +612,7 @@ static void adreno_shutdown(struct platform_device *pdev)
  {
struct msm_gpu *gpu = dev_to_gpu(>dev);
  
+	gpu->is_shutdown = true;

WARN_ON_ONCE(adreno_system_suspend(>dev));
  }
  
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c

index 382fb7f9e497..6903c6892469 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -251,7 +251,7 @@ int adreno_get_param(struct msm_gpu *gpu, struct 
msm_file_private *ctx,
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
  
  	/* No pointer params yet */

-   if (*len != 0)
+   if (*len != 0 || gpu->is_shutdown)
return -EINVAL;
This will race with shutdown. Probably, propagating back the return 
value of pm_runtime_get() in every possible ioctl call path is the right 
thing to do.


I have never thought about this scenario. Do you know why userspace is 
not freezed before kexec?


-Akhil.
  
  	switch (param) {

diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index ff911e7305ce..f18b0a91442b 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -214,6 +214,9 @@ struct msm_gpu {
/* does gpu need hw_init? */
bool needs_hw_init;
  
+	/* is the GPU shutdown? */

+   bool is_shutdown;
+
/**
 * global_faults: number of GPU hangs not attributed to a particular
 * address space




Re: [PATCH 1/2] drm/vc4: hdmi: Enforce the minimum rate at runtime_resume

2022-11-11 Thread Stefan Wahren

Hi Maxime,

Am 29.09.22 um 11:21 schrieb Maxime Ripard:

This is a revert of commit fd5894fa2413 ("drm/vc4: hdmi: Remove clock
rate initialization"), with the code slightly moved around.

It turns out that we can't downright remove that code from the driver,
since the Pi0-3 and Pi4 are in different cases, and it only works for
the Pi4.

Indeed, the commit mentioned above was relying on the RaspberryPi
firmware clocks driver to initialize the rate if it wasn't done by the
firmware. However, the Pi0-3 are using the clk-bcm2835 clock driver that
wasn't doing this initialization. We therefore end up with the clock not
being assigned a rate, and the CPU stalling when trying to access a
register.

We can't move that initialization in the clk-bcm2835 driver, since the
HSM clock we depend on is actually part of the HDMI power domain, so any
rate setup is only valid when the power domain is enabled. Thus, we
reinstated the minimum rate setup at runtime_suspend, which should
address both issues.

Link: 
https://lore.kernel.org/dri-devel/20220922145448.w3xfywkn5ecak...@pengutronix.de/
Fixes: fd5894fa2413 ("drm/vc4: hdmi: Remove clock rate initialization")
Reported-by: Marc Kleine-Budde 
Signed-off-by: Maxime Ripard 
---
  drivers/gpu/drm/vc4/vc4_hdmi.c | 9 +
  1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 199bc398817f..2e28fe16ed5e 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -2891,6 +2891,15 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
u32 __maybe_unused value;
int ret;
  
+	/*

+* The HSM clock is in the HDMI power domain, so we need to set
+* its frequency while the power domain is active so that it
+* keeps its rate.
+*/
+   ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ);
+   if (ret)
+   return ret;
+


unfortunately this breaks X on Raspberry Pi 4 in Linux 6.0.5 
(multi_v7_defconfig + LPAE). Today i saw this report [1] and bisected 
the issue down to this patch. Shame on me that i only tested this patch 
with Rpi 3B+ :-(


Best regards

[1] - https://bugzilla.suse.com/show_bug.cgi?id=1205259


ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
if (ret)
return ret;



Re: [PATCH 1/2] adreno: Shutdown the GPU properly

2022-11-11 Thread Joel Fernandes



> On Nov 11, 2022, at 2:50 PM, Joel Fernandes (Google)  
> wrote:
> 
> During kexec on ARM device, we notice that device_shutdown() only calls
> pm_runtime_force_suspend() while shutting down the GPU. This means the GPU
> kthread is still running and further, there maybe active submits.
> 
> This causes all kinds of issues during a kexec reboot:
> 
> Warning from shutdown path:
> 
> [  292.509662] WARNING: CPU: 0 PID: 6304 at [...] 
> adreno_runtime_suspend+0x3c/0x44
> [  292.509863] Hardware name: Google Lazor (rev3 - 8) with LTE (DT)
> [  292.509872] pstate: 8049 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [  292.509881] pc : adreno_runtime_suspend+0x3c/0x44
> [  292.509891] lr : pm_generic_runtime_suspend+0x30/0x44
> [  292.509905] sp : ffc014473bf0
> [...]
> [  292.510043] Call trace:
> [  292.510051]  adreno_runtime_suspend+0x3c/0x44
> [  292.510061]  pm_generic_runtime_suspend+0x30/0x44
> [  292.510071]  pm_runtime_force_suspend+0x54/0xc8
> [  292.510081]  adreno_shutdown+0x1c/0x28
> [  292.510090]  platform_shutdown+0x2c/0x38
> [  292.510104]  device_shutdown+0x158/0x210
> [  292.510119]  kernel_restart_prepare+0x40/0x4c
> 
> And here from GPU kthread, an SError OOPs:
> 
> [  192.648789]  el1h_64_error+0x7c/0x80
> [  192.648812]  el1_interrupt+0x20/0x58
> [  192.648833]  el1h_64_irq_handler+0x18/0x24
> [  192.648854]  el1h_64_irq+0x7c/0x80
> [  192.648873]  local_daif_inherit+0x10/0x18
> [  192.648900]  el1h_64_sync_handler+0x48/0xb4
> [  192.648921]  el1h_64_sync+0x7c/0x80
> [  192.648941]  a6xx_gmu_set_oob+0xbc/0x1fc
> [  192.648968]  a6xx_hw_init+0x44/0xe38
> [  192.648991]  msm_gpu_hw_init+0x48/0x80
> [  192.649013]  msm_gpu_submit+0x5c/0x1a8
> [  192.649034]  msm_job_run+0xb0/0x11c
> [  192.649058]  drm_sched_main+0x170/0x434
> [  192.649086]  kthread+0x134/0x300
> [  192.649114]  ret_from_fork+0x10/0x20
> 
> Fix by calling adreno_system_suspend() in the device_shutdown() path.
> 
> Cc: Rob Clark 
> Cc: Steven Rostedt 
> Cc: Ricardo Ribalda 
> Cc: Ross Zwisler 
> Signed-off-by: Joel Fernandes (Google) 
> ---
> drivers/gpu/drm/msm/adreno/adreno_device.c | 5 -
> 1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
> b/drivers/gpu/drm/msm/adreno/adreno_device.c
> index 24b489b6129a..f0cff62812c3 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
> @@ -607,9 +607,12 @@ static int adreno_remove(struct platform_device *pdev)
>return 0;
> }
> 
> +static int adreno_system_suspend(struct device *dev);
> static void adreno_shutdown(struct platform_device *pdev)
> {
> -pm_runtime_force_suspend(>dev);
> +struct msm_gpu *gpu = dev_to_gpu(>dev);
> +

This local variable definition should go to patch 2/2. Will fix in v2.

Thanks,

 - Joel


> +WARN_ON_ONCE(adreno_system_suspend(>dev));
> }
> 
> static const struct of_device_id dt_match[] = {
> -- 
> 2.38.1.493.g58b659f92b-goog
> 


Re: [PATCH v1 0/6] Move dma_buf_mmap_internal() to dynamic locking specification

2022-11-11 Thread Dmitry Osipenko
On 11/10/22 23:13, Dmitry Osipenko wrote:
> Hello,
> 
> Recently, dma-buf got a common locking convention for importers and
> exporters. All the dma-buf functions were moved to the new locking
> convention, apart from the dma_buf_mmap_internal() that was missed out
> by accident. This series moves dma_buf_mmap_internal() to the dynamic
> locking specification and updates drivers that support mmaping of
> dma-bufs to use the debug-assert of the lock.
> 
> Thanks to Daniel Vetter for spotting the missed function!
> 
> Dmitry Osipenko (6):
>   dma-buf: Move dma_buf_mmap_internal() to dynamic locking specification
>   drm: Assert held reservation lock for dma-buf mmapping
>   udmabuf: Assert held reservation lock for dma-buf mmapping
>   dma-buf/heaps: Assert held reservation lock for dma-buf mmapping
>   media: videobuf2: Assert held reservation lock for dma-buf mmapping
>   fastrpc: Assert held reservation lock for dma-buf mmapping
> 
>  drivers/dma-buf/dma-buf.c | 7 ++-
>  drivers/dma-buf/heaps/cma_heap.c  | 3 +++
>  drivers/dma-buf/heaps/system_heap.c   | 3 +++
>  drivers/dma-buf/udmabuf.c | 3 +++
>  drivers/gpu/drm/drm_prime.c   | 2 ++
>  drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c| 2 ++
>  drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c | 2 ++
>  drivers/gpu/drm/tegra/gem.c   | 2 ++
>  drivers/media/common/videobuf2/videobuf2-dma-contig.c | 3 +++
>  drivers/media/common/videobuf2/videobuf2-dma-sg.c | 3 +++
>  drivers/media/common/videobuf2/videobuf2-vmalloc.c| 3 +++
>  drivers/misc/fastrpc.c| 3 +++
>  12 files changed, 35 insertions(+), 1 deletion(-)
> 

Applied to drm-misc-next

-- 
Best regards,
Dmitry



[PATCH 1/2] adreno: Shutdown the GPU properly

2022-11-11 Thread Joel Fernandes (Google)
During kexec on ARM device, we notice that device_shutdown() only calls
pm_runtime_force_suspend() while shutting down the GPU. This means the GPU
kthread is still running and further, there maybe active submits.

This causes all kinds of issues during a kexec reboot:

Warning from shutdown path:

[  292.509662] WARNING: CPU: 0 PID: 6304 at [...] 
adreno_runtime_suspend+0x3c/0x44
[  292.509863] Hardware name: Google Lazor (rev3 - 8) with LTE (DT)
[  292.509872] pstate: 8049 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  292.509881] pc : adreno_runtime_suspend+0x3c/0x44
[  292.509891] lr : pm_generic_runtime_suspend+0x30/0x44
[  292.509905] sp : ffc014473bf0
[...]
[  292.510043] Call trace:
[  292.510051]  adreno_runtime_suspend+0x3c/0x44
[  292.510061]  pm_generic_runtime_suspend+0x30/0x44
[  292.510071]  pm_runtime_force_suspend+0x54/0xc8
[  292.510081]  adreno_shutdown+0x1c/0x28
[  292.510090]  platform_shutdown+0x2c/0x38
[  292.510104]  device_shutdown+0x158/0x210
[  292.510119]  kernel_restart_prepare+0x40/0x4c

And here from GPU kthread, an SError OOPs:

[  192.648789]  el1h_64_error+0x7c/0x80
[  192.648812]  el1_interrupt+0x20/0x58
[  192.648833]  el1h_64_irq_handler+0x18/0x24
[  192.648854]  el1h_64_irq+0x7c/0x80
[  192.648873]  local_daif_inherit+0x10/0x18
[  192.648900]  el1h_64_sync_handler+0x48/0xb4
[  192.648921]  el1h_64_sync+0x7c/0x80
[  192.648941]  a6xx_gmu_set_oob+0xbc/0x1fc
[  192.648968]  a6xx_hw_init+0x44/0xe38
[  192.648991]  msm_gpu_hw_init+0x48/0x80
[  192.649013]  msm_gpu_submit+0x5c/0x1a8
[  192.649034]  msm_job_run+0xb0/0x11c
[  192.649058]  drm_sched_main+0x170/0x434
[  192.649086]  kthread+0x134/0x300
[  192.649114]  ret_from_fork+0x10/0x20

Fix by calling adreno_system_suspend() in the device_shutdown() path.

Cc: Rob Clark 
Cc: Steven Rostedt 
Cc: Ricardo Ribalda 
Cc: Ross Zwisler 
Signed-off-by: Joel Fernandes (Google) 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 24b489b6129a..f0cff62812c3 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -607,9 +607,12 @@ static int adreno_remove(struct platform_device *pdev)
return 0;
 }
 
+static int adreno_system_suspend(struct device *dev);
 static void adreno_shutdown(struct platform_device *pdev)
 {
-   pm_runtime_force_suspend(>dev);
+   struct msm_gpu *gpu = dev_to_gpu(>dev);
+
+   WARN_ON_ONCE(adreno_system_suspend(>dev));
 }
 
 static const struct of_device_id dt_match[] = {
-- 
2.38.1.493.g58b659f92b-goog



[PATCH 2/2] adreno: Detect shutdown during get_param()

2022-11-11 Thread Joel Fernandes (Google)
Even though the GPU is shut down, during kexec reboot we can have userspace
still running. This is especially true if KEXEC_JUMP is not enabled, because we
do not freeze userspace in this case.

To prevent crashes, track that the GPU is shutdown and prevent get_param() from
accessing GPU resources if we find it shutdown.

This fixes the following crash during kexec reboot on an ARM64 device with 
adreno GPU:

[  292.534314] Kernel panic - not syncing: Asynchronous SError Interrupt
[  292.534323] Hardware name: Google Lazor (rev3 - 8) with LTE (DT)
[  292.534326] Call trace:
[  292.534328]  dump_backtrace+0x0/0x1d4
[  292.534337]  show_stack+0x20/0x2c
[  292.534342]  dump_stack_lvl+0x60/0x78
[  292.534347]  dump_stack+0x18/0x38
[  292.534352]  panic+0x148/0x3b0
[  292.534357]  nmi_panic+0x80/0x94
[  292.534364]  arm64_serror_panic+0x70/0x7c
[  292.534369]  do_serror+0x0/0x7c
[  292.534372]  do_serror+0x54/0x7c
[  292.534377]  el1h_64_error_handler+0x34/0x4c
[  292.534381]  el1h_64_error+0x7c/0x80
[  292.534386]  el1_interrupt+0x20/0x58
[  292.534389]  el1h_64_irq_handler+0x18/0x24
[  292.534395]  el1h_64_irq+0x7c/0x80
[  292.534399]  local_daif_inherit+0x10/0x18
[  292.534405]  el1h_64_sync_handler+0x48/0xb4
[  292.534410]  el1h_64_sync+0x7c/0x80
[  292.534414]  a6xx_gmu_set_oob+0xbc/0x1fc
[  292.534422]  a6xx_get_timestamp+0x40/0xb4
[  292.534426]  adreno_get_param+0x12c/0x1e0
[  292.534433]  msm_ioctl_get_param+0x64/0x70
[  292.534440]  drm_ioctl_kernel+0xe8/0x158
[  292.534448]  drm_ioctl+0x208/0x320
[  292.534453]  __arm64_sys_ioctl+0x98/0xd0
[  292.534461]  invoke_syscall+0x4c/0x118
[  292.534467]  el0_svc_common+0x98/0x104
[  292.534473]  do_el0_svc+0x30/0x80
[  292.534478]  el0_svc+0x20/0x50
[  292.534481]  el0t_64_sync_handler+0x78/0x108
[  292.534485]  el0t_64_sync+0x1a4/0x1a8
[  292.534632] Kernel Offset: 0x1a5f80 from 0xffc00800
[  292.534635] PHYS_OFFSET: 0x8000
[  292.534638] CPU features: 0x40018541,a3300e42
[  292.534644] Memory Limit: none

Cc: Rob Clark 
Cc: Steven Rostedt 
Cc: Ricardo Ribalda 
Cc: Ross Zwisler 
Signed-off-by: Joel Fernandes (Google) 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 1 +
 drivers/gpu/drm/msm/adreno/adreno_gpu.c| 2 +-
 drivers/gpu/drm/msm/msm_gpu.h  | 3 +++
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index f0cff62812c3..03d912dc0130 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -612,6 +612,7 @@ static void adreno_shutdown(struct platform_device *pdev)
 {
struct msm_gpu *gpu = dev_to_gpu(>dev);
 
+   gpu->is_shutdown = true;
WARN_ON_ONCE(adreno_system_suspend(>dev));
 }
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 382fb7f9e497..6903c6892469 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -251,7 +251,7 @@ int adreno_get_param(struct msm_gpu *gpu, struct 
msm_file_private *ctx,
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 
/* No pointer params yet */
-   if (*len != 0)
+   if (*len != 0 || gpu->is_shutdown)
return -EINVAL;
 
switch (param) {
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index ff911e7305ce..f18b0a91442b 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -214,6 +214,9 @@ struct msm_gpu {
/* does gpu need hw_init? */
bool needs_hw_init;
 
+   /* is the GPU shutdown? */
+   bool is_shutdown;
+
/**
 * global_faults: number of GPU hangs not attributed to a particular
 * address space
-- 
2.38.1.493.g58b659f92b-goog



Re: [PATCH] drm/edid: Dump the EDID when drm_edid_get_panel_id() has an error

2022-11-11 Thread Doug Anderson
Hi,

On Tue, Oct 25, 2022 at 1:39 PM Abhinav Kumar  wrote:
>
> Hi Doug
>
> On 10/24/2022 1:28 PM, Doug Anderson wrote:
> > Hi,
> >
> > On Fri, Oct 21, 2022 at 2:18 PM Abhinav Kumar  
> > wrote:
> >>
> >> Hi Doug
> >>
> >> On 10/21/2022 1:07 PM, Douglas Anderson wrote:
> >>> If we fail to get a valid panel ID in drm_edid_get_panel_id() we'd
> >>> like to see the EDID that was read so we have a chance of
> >>> understanding what's wrong. There's already a function for that, so
> >>> let's call it in the error case.
> >>>
> >>> NOTE: edid_block_read() has a retry loop in it, so actually we'll only
> >>> print the block read back from the final attempt. This still seems
> >>> better than nothing.
> >>>
> >>> Signed-off-by: Douglas Anderson 
> >>
> >> Instead of checkinf for edid_block_status_valid() on the base_block, do
> >> you want to use drm_edid_block_valid() instead?
> >>
> >> That way you get the edid_block_dump() for free if it was invalid.
> >
> > I can... ...but it feels a bit awkward and maybe not quite how the
> > functions were intended to work together?
> >
> > One thing I notice is that if I call drm_edid_block_valid() I'm doing
> > a bunch of duplicate work that already happened in edid_block_read(),
> > which already calls edid_block_check() and handles fixing headers. I
> > guess also if I call drm_edid_block_valid() then I should ignore the
> > "status" return value of edid_block_read() because we don't need to
> > pass it anywhere (because the work is re-done in
> > drm_edid_block_valid()).
> >
> > So I guess I'm happy to do a v2 like that if everyone likes it better,
> > but to me it feels a little weird.
> >
> > -Doug
>
> Alright, agreed. There is some duplication of code happening if we use
> drm_edid_block_valid(). I had suggested that because it has inherent
> support for dumping the bad EDID.
>
> In that case, this change LGTM, because in principle you are doing the
> same thing as _drm_do_get_edid() (with the only difference being here we
> read only the base block as opposed to the full EDID there).
>
> Hence,
>
> Reviewed-by: Abhinav Kumar 

I've given this patch a bunch of time because it wasn't urgent, but
seems like it could be about time to land. I'll plan to land it next
Monday or Tuesday unless anyone has any other comments.

Thanks!

-Doug


Re: [PATCH] drm/panel-edp: Use ktime_get_boottime for delays

2022-11-11 Thread Doug Anderson
Hi,

On Thu, Nov 10, 2022 at 1:51 PM Drew Davenport  wrote:
>
> ktime_get is based on CLOCK_MONOTONIC which stops on suspend. On
> suspend, the time that the panel was powerd off is recorded with
> ktime_get, and on resume this time is compared to the current ktime_get
> time to determine if the driver should wait for the panel to power down
> completely before re-enabling it.
>
> Because we're using ktime_get, this delay doesn't account for the time
> that the device is suspended, during which the power down delay may have
> already elapsed.
>
> Change to use ktime_get_boottime throughout, which uses CLOCK_BOOTTIME
> which does not stop when suspended. This ensures that the resume path
> will not be delayed if the power off delay has already been met while
> the device is suspended.
>
> Signed-off-by: Drew Davenport 
>
> ---
>
>  drivers/gpu/drm/panel/panel-edp.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)

Nice!

Reviewed-by: Douglas Anderson 

My plan will be to land this to drm-misc-next early next week (Tuesday
maybe?) unless someone has any objections.

BTW: any chance you'd be willing to post against two similar drivers:
panel-simple.c and panel-samsung-atna33xc20.c? They have nearly the
same code (and, yes, these drivers are purposely copies since there
was overall consensus that having one giant panel driver to handle all
possible panels was getting far too confusing)

-Doug


Re: Coverity: nouveau_dp_irq(): Null pointer dereferences

2022-11-11 Thread Karol Herbst
On Fri, Nov 11, 2022 at 9:16 PM Kees Cook  wrote:
>
> On Fri, Nov 11, 2022 at 09:06:54PM +0100, Karol Herbst wrote:
> > On Fri, Nov 11, 2022 at 8:21 PM Kees Cook  wrote:
> > >
> > > On Fri, Nov 11, 2022 at 11:13:17AM +0200, Jani Nikula wrote:
> > > > On Thu, 10 Nov 2022, coverity-bot  wrote:
> > > > > Hello!
> > > > >
> > > > > This is an experimental semi-automated report about issues detected by
> > > > > Coverity from a scan of next-20221110 as part of the linux-next scan 
> > > > > project:
> > > > > https://scan.coverity.com/projects/linux-next-weekly-scan
> > > > >
> > > > > You're getting this email because you were associated with the 
> > > > > identified
> > > > > lines of code (noted below) that were touched by commits:
> > > > >
> > > > >   Mon Aug 31 19:10:08 2020 -0400
> > > > > a0922278f83e ("drm/nouveau/kms/nv50-: Refactor and cleanup DP HPD 
> > > > > handling")
> > > >
> > > > Hi Kees, this looks like a good idea, but maybe double check the Cc list
> > > > generation? I was Cc'd on four mails today that I thought were
> > > > irrelevant to me.
> > >
> > > Hi!
> > >
> > > Heh, I was recently asked to _expand_ the CC list. :)
> > >
> > > For these last pass of reports, I added a get_maintainers.pl run to the
> > > identified commit. In this instance, the commit touched:
> > >
> > >  drivers/gpu/drm/nouveau/dispnv04/disp.c |6 +
> > >  drivers/gpu/drm/nouveau/dispnv50/disp.c |  192 
> > > ++--
> > >  drivers/gpu/drm/nouveau/nouveau_connector.c |   14 ---
> > >  drivers/gpu/drm/nouveau/nouveau_display.c   |2
> > >  drivers/gpu/drm/nouveau/nouveau_display.h   |2
> > >  drivers/gpu/drm/nouveau/nouveau_dp.c|  132 
> > > -
> > >  drivers/gpu/drm/nouveau/nouveau_encoder.h   |   33 +++-
> > >  7 files changed, 244 insertions(+), 137 deletions(-)
> > >
> > > And the get_maintainers.pl rationale was:
> > >
> > > Ben Skeggs  (supporter:DRM DRIVER FOR NVIDIA 
> > > GEFORCE/QUADRO 
> > > GPUS,commit_signer:1/1=100%,commit_signer:6/16=38%,authored:4/16=25%,added_lines:23/124=19%,removed_lines:36/152=24%)
> > > Karol Herbst  (supporter:DRM DRIVER FOR NVIDIA 
> > > GEFORCE/QUADRO GPUS,commit_signer:2/1=100%)
> > > Lyude Paul  (supporter:DRM DRIVER FOR NVIDIA 
> > > GEFORCE/QUADRO 
> > > GPUS,commit_signer:9/16=56%,authored:6/16=38%,added_lines:92/124=74%,removed_lines:107/152=70%)
> > > David Airlie  (maintainer:DRM DRIVERS)
> > > Daniel Vetter  (maintainer:DRM DRIVERS)
> > > Ilia Mirkin  
> > > (commit_signer:1/1=100%,authored:1/1=100%,added_lines:2/2=100%,removed_lines:2/2=100%)
> > > "Nathan E. Egge"  (commit_signer:1/1=100%)
> > > Jani Nikula  (commit_signer:6/16=38%)
> > > Dave Airlie  (commit_signer:5/16=31%)
> > > Thomas Zimmermann  
> > > (commit_signer:4/16=25%,authored:4/16=25%)
> > > dri-devel@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA 
> > > GEFORCE/QUADRO GPUS)
> > > nouv...@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA 
> > > GEFORCE/QUADRO GPUS)
> > >
> >
> > I'd say it's good enough to message supporters and the mailing lists
> > for at least Nouveau code, maybe even all drm drivers.
>
> i.e. leave out the commit_signer hits?
>

yes.

> > Not sure what to do about actual maintainers, but I doubt Dave and
> > Daniel want to be CCed on every Coverity report here either.
>
> I updated the CC logic based on this feedback:
> https://lore.kernel.org/linux-hardening/87h6zgfub4@kernel.org/
>
> So maybe just mailing lists?
>

That should be good enough, but maybe the DRM subsystem is big enough
so it's reasonable to add special rules. For Nouveau either way is
fine.

> --
> Kees Cook
>



[PATCH V5 2/3] dt-bindings: display: panel: Add NewVision NV3051D bindings

2022-11-11 Thread Chris Morgan
From: Chris Morgan 

Add documentation for the NewVision NV3051D panel bindings.
Note that for the two expected consumers of this panel binding
the underlying LCD model is unknown. Name "anbernic,rg353p-panel"
is used because the hardware itself is known as "anbernic,rg353p".

Signed-off-by: Chris Morgan 
Reviewed-by: Rob Herring 
---
 .../display/panel/newvision,nv3051d.yaml  | 63 +++
 1 file changed, 63 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml 
b/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml
new file mode 100644
index ..116c1b6030a2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/newvision,nv3051d.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NewVision NV3051D based LCD panel
+
+description: |
+  The NewVision NV3051D is a driver chip used to drive DSI panels. For now,
+  this driver only supports the 640x480 panels found in the Anbernic RG353
+  based devices.
+
+maintainers:
+  - Chris Morgan 
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+items:
+  - enum:
+  - anbernic,rg353p-panel
+  - anbernic,rg353v-panel
+  - const: newvision,nv3051d
+
+  reg: true
+  backlight: true
+  port: true
+  reset-gpios:
+description: Active low reset GPIO
+  vdd-supply: true
+
+required:
+  - compatible
+  - reg
+  - backlight
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+dsi {
+#address-cells = <1>;
+#size-cells = <0>;
+panel@0 {
+compatible = "anbernic,rg353p-panel", "newvision,nv3051d";
+reg = <0>;
+backlight = <>;
+reset-gpios = < 0 GPIO_ACTIVE_LOW>;
+vdd-supply = <_lcd>;
+
+port {
+mipi_in_panel: endpoint {
+remote-endpoint = <_out_panel>;
+};
+};
+};
+};
+
+...
-- 
2.25.1



[PATCH V5 3/3] drm/panel: Add NewVision NV3051D MIPI-DSI LCD panel

2022-11-11 Thread Chris Morgan
From: Chris Morgan 

Support NewVision NV3051D panels as found on the Anbernic RG353P and
RG353V. The underlying LCD part number for the RG353x devices is
unknown, so the device name and a fallback for the driver IC is
used instead.

Signed-off-by: Chris Morgan 
---
 drivers/gpu/drm/panel/Kconfig |   9 +
 drivers/gpu/drm/panel/Makefile|   1 +
 .../gpu/drm/panel/panel-newvision-nv3051d.c   | 504 ++
 3 files changed, 514 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-newvision-nv3051d.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index a582ddd583c2..427c22bdbfb3 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -296,6 +296,15 @@ config DRM_PANEL_NEC_NL8048HL11
  panel (found on the Zoom2/3/3630 SDP boards). To compile this driver
  as a module, choose M here.
 
+config DRM_PANEL_NEWVISION_NV3051D
+   tristate "NewVision NV3051D DSI panel"
+   depends on OF
+   depends on DRM_MIPI_DSI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ This driver supports the NV3051D based panel found on the Anbernic
+ RG353P and RG353V.
+
 config DRM_PANEL_NEWVISION_NV3052C
tristate "NewVision NV3052C RGB/SPI panel"
depends on OF && SPI
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 34e717382dbb..cb03b3a82738 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += 
panel-leadtek-ltk500hd1829.o
 obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
 obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
+obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o
 obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35560) += panel-novatek-nt35560.o
diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3051d.c 
b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c
new file mode 100644
index ..305b2aae059f
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c
@@ -0,0 +1,504 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NV3051D MIPI-DSI panel driver for Anbernic RG353x
+ * Copyright (C) 2022 Chris Morgan
+ *
+ * based on
+ *
+ * Elida kd35t133 3.5" MIPI-DSI panel driver
+ * Copyright (C) Theobroma Systems 2020
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+struct nv3051d_panel_info {
+   const struct drm_display_mode *display_modes;
+   unsigned int num_modes;
+   u16 width_mm, height_mm;
+   u32 bus_flags;
+};
+
+struct panel_nv3051d {
+   struct device *dev;
+   struct drm_panel panel;
+   struct gpio_desc *reset_gpio;
+   const struct nv3051d_panel_info *panel_info;
+   struct regulator *vdd;
+};
+
+static inline struct panel_nv3051d *panel_to_panelnv3051d(struct drm_panel 
*panel)
+{
+   return container_of(panel, struct panel_nv3051d, panel);
+}
+
+static int panel_nv3051d_init_sequence(struct panel_nv3051d *ctx)
+{
+   struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+   /*
+* Init sequence was supplied by device vendor with no
+* documentation.
+*/
+
+   mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x30);
+   mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x52);
+   mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x01);
+   mipi_dsi_dcs_write_seq(dsi, 0xE3, 0x00);
+   mipi_dsi_dcs_write_seq(dsi, 0x03, 0x40);
+   mipi_dsi_dcs_write_seq(dsi, 0x04, 0x00);
+   mipi_dsi_dcs_write_seq(dsi, 0x05, 0x03);
+   mipi_dsi_dcs_write_seq(dsi, 0x24, 0x12);
+   mipi_dsi_dcs_write_seq(dsi, 0x25, 0x1E);
+   mipi_dsi_dcs_write_seq(dsi, 0x26, 0x28);
+   mipi_dsi_dcs_write_seq(dsi, 0x27, 0x52);
+   mipi_dsi_dcs_write_seq(dsi, 0x28, 0x57);
+   mipi_dsi_dcs_write_seq(dsi, 0x29, 0x01);
+   mipi_dsi_dcs_write_seq(dsi, 0x2A, 0xDF);
+   mipi_dsi_dcs_write_seq(dsi, 0x38, 0x9C);
+   mipi_dsi_dcs_write_seq(dsi, 0x39, 0xA7);
+   mipi_dsi_dcs_write_seq(dsi, 0x3A, 0x53);
+   mipi_dsi_dcs_write_seq(dsi, 0x44, 0x00);
+   mipi_dsi_dcs_write_seq(dsi, 0x49, 0x3C);
+   mipi_dsi_dcs_write_seq(dsi, 0x59, 0xFE);
+   mipi_dsi_dcs_write_seq(dsi, 0x5C, 0x00);
+   mipi_dsi_dcs_write_seq(dsi, 0x91, 0x77);
+   mipi_dsi_dcs_write_seq(dsi, 0x92, 0x77);
+   mipi_dsi_dcs_write_seq(dsi, 0xA0, 0x55);
+   mipi_dsi_dcs_write_seq(dsi, 0xA1, 0x50);
+   mipi_dsi_dcs_write_seq(dsi, 0xA4, 0x9C);
+   mipi_dsi_dcs_write_seq(dsi, 0xA7, 0x02);
+   mipi_dsi_dcs_write_seq(dsi, 0xA8, 0x01);
+   mipi_dsi_dcs_write_seq(dsi, 0xA9, 0x01);
+   mipi_dsi_dcs_write_seq(dsi, 0xAA, 0xFC);
+   

[PATCH V5 1/3] dt-bindings: vendor-prefixes: add NewVision vendor prefix

2022-11-11 Thread Chris Morgan
From: Chris Morgan 

NewVision (also sometimes written as New Vision) is a company based in
Shenzen that manufactures ICs for controlling LCD panels.

https://www.newvisiondisplay.com/

Signed-off-by: Chris Morgan 
Acked-by: Krzysztof Kozlowski 
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml 
b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 6e323a380294..c6aa7b3d1455 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -883,6 +883,8 @@ patternProperties:
 description: Shenzhen Netxeon Technology CO., LTD
   "^neweast,.*":
 description: Guangdong Neweast Optoelectronics CO., LTD
+  "^newvision,.*":
+description: New Vision Display (Shenzhen) Co., Ltd.
   "^nexbox,.*":
 description: Nexbox
   "^nextthing,.*":
-- 
2.25.1



[PATCH V5 0/3] drm/panel: Add NewVision NV3051D Panels

2022-11-11 Thread Chris Morgan
From: Chris Morgan 

Add the NewVision NV3051D panel as found on the Anbernic RG353P and
RG353V. The underlying LCD panel itself is unknown (the NV3051D is
the controller), so the device name is used for the panel with a
fallback to the driver IC.

Changes from V4:
 - Removed "prepared" as its tracked by the framework.
 - Use mipi_dsi_dcs_write_seq instead of custom implementation.
 - Changed devm_gpiod_get_optional to assert GPIO as high at probe so
   it is held in reset on suggestion from maintainer.
 - Removed requirement for vdd-supply in documentation.
 - Added description in documentation for reset gpio to note it should
   be active low.

Changes from V3:
 - Changed driver remove function from int to void to match change
   made to mipi_dsi_driver struct.

Changes from V2:
 - Ensured dt_binding_check and dtbs_check successfully passed.
 - Corrected some minor formatting issues in documentation.
 - Added another mode per userspace request for 100hz. I was unable
   to find a supported 50hz mode that would also work, so for now
   only 60hz, 100hz, and 120hz are supported.

Changes from V1:
 - Changed compatible string to the driver IC.
 - Updated documentation to use new compatible string with board
   name.
 - Refactored somewhat to make it easier to support other LCD panels
   with this kernel module.
 - Added support for 60hz mode. Adjusted pixel clock to ensure proper
   60hz and 120hz (previously was running at 124hz).
 - Added vendor prefix for NewVision. Anbernic vendor prefix added in
   
https://lore.kernel.org/linux-devicetree/20220906210324.28986-2-macroalph...@gmail.com

Chris Morgan (3):
  dt-bindings: vendor-prefixes: add NewVision vendor prefix
  dt-bindings: display: panel: Add NewVision NV3051D  bindings
  drm/panel: Add NewVision NV3051D MIPI-DSI LCD panel

 .../display/panel/newvision,nv3051d.yaml  |  63 +++
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 drivers/gpu/drm/panel/Kconfig |   9 +
 drivers/gpu/drm/panel/Makefile|   1 +
 .../gpu/drm/panel/panel-newvision-nv3051d.c   | 504 ++
 5 files changed, 579 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml
 create mode 100644 drivers/gpu/drm/panel/panel-newvision-nv3051d.c

-- 
2.25.1



[pull] amdgpu, amdkfd, radeon drm-next-6.2

2022-11-11 Thread Alex Deucher
Hi Dave, Daniel,

More new stuff for 6.2.

The following changes since commit a143bc517bf31c4575191efbaac216a11ec016e0:

  Merge branch '00.06-gr-ampere' of 
https://gitlab.freedesktop.org/skeggsb/nouveau into drm-next (2022-11-09 
11:18:56 +1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-next-6.2-2022-11-11

for you to fetch changes up to 2ebf61f2cfb9a11bc17db30df3e675a4cd7418d3:

  drm/amdgpu: Fix memory leak in amdgpu_cs_pass1 (2022-11-10 15:30:34 -0500)


amd-drm-next-6.2-2022-11-11:

amdgpu:
- SMU 13.x updates
- GPUVM TLB race fix
- DCN 3.1.4 updates
- DCN 3.2.x updates
- PSR fixes
- Kerneldoc fix
- Vega10 fan fix
- GPUVM locking fixes in error pathes
- BACO fix for Beige Goby
- EEPROM I2C address cleanup
- GFXOFF fix
- Fix DC memory leak in error pathes
- Flexible array updates
- Mtype fix for GPUVM PTEs
- Move Kconfig into amdgpu directory
- SR-IOV updates
- Fix possible memory leak in CS IOCTL error path

amdkfd:
- Fix possible memory overrun
- CRIU fixes

radeon:
- ACPI ref count fix
- HDA audio notifier support
- Move Kconfig into radeon directory

UAPI:
- Add new GEM_CREATE flags to help to transition more KFD functionality to the 
DRM UAPI.
  These are used internally in the driver to align location based memory 
coherency
  requirements from memory allocated in the KFD with how we manage GPUVM PTEs.  
They
  are currently blocked in the GEM_CREATE IOCTL as we don't have a user right 
now.
  They are just used internally in the kernel driver for now for existing KFD 
memory
  allocations. So a change to the UAPI header, but no functional change in the 
UAPI.


Alvin Lee (4):
  drm/amd/display: Wait for VBLANK during pipe programming
  drm/amd/display: Use min transition for SubVP into MPO
  drm/amd/display: Disable phantom OTG after enable for plane disable
  drm/amd/display: Add margin for max vblank time for SubVP + DRR

Andrew Davis (1):
  drm: Move radeon and amdgpu Kconfig options into their directories

Aric Cyr (1):
  drm/amd/display: 3.2.211

Asher Song (1):
  Revert "drm/amdgpu: Revert "drm/amdgpu: getting fan speed pwm for vega10 
properly""

Aurabindo Pillai (1):
  drm/amd/display: Zeromem mypipe heap struct before using it

Chaitanya Dhere (1):
  drm/amd/display: Fix FCLK deviation and tool compile issues

Christian König (1):
  drm/amdgpu: workaround for TLB seq race

Dillon Varone (1):
  drm/amd/display: Enforce minimum prefetch time for low memclk on DCN32

Dong Chenchen (1):
  drm/amdgpu: Fix memory leak in amdgpu_cs_pass1

Felix Kuehling (3):
  drm/amdkfd: Fix error handling in kfd_criu_restore_events
  drm/amdkfd: Fix error handling in criu_checkpoint
  drm/amdgpu: Set MTYPE in PTE based on BO flags

Gavin Wan (1):
  drm/amdgpu: Ignore stop rlc on SRIOV environment.

George Shen (1):
  drm/amd/display: Populate DP2.0 output type for DML pipe

Guchun Chen (1):
  drm/amdgpu: disable BACO on special BEIGE_GOBY card

Hamza Mahfooz (1):
  drm/amd/display: only fill dirty rectangles when PSR is enabled

Hanjun Guo (1):
  drm/radeon: Add the missed acpi_put_table() to fix memory leak

Harsh Jain (1):
  drm/amdgpu: complete gfxoff allow signal during suspend without delay

Kenneth Feng (2):
  drm/amd/pm: enable mode1 reset on smu_v13_0_10
  drm/amd/pm: skip disabling all smu features on smu_v13_0_10 in suspend

Leo Ma (1):
  drm/amd/display: Adding HDMI SCDC DEVICE_ID define

Liu Jian (1):
  drm/amd/display: delete the duplicate .set_odm_bypass initialization in 
dcn314_tg_funcs

LongJun Tang (1):
  drm/amd/display: Have risk for memory exhaustion

Luben Tuikov (2):
  drm/amdgpu: Remove redundant I2C EEPROM address
  drm/amdgpu: Decouple RAS EEPROM addresses from chips

Ma Jun (2):
  drm/amdkfd: Fix the memory overrun
  drm/amdkfd: Make kfd_fill_cache_non_crat_info() as static

Max Tseng (1):
  drm/amd/display: Cursor update refactor: PSR-SU support condition

Michael Strauss (1):
  drm/amd/display: Only update link settings after successful MST link train

Mike Hsieh (1):
  drm/amd/display: Set correct EOTF and Gamut flag in VRR info

Mustapha Ghaddar (1):
  drm/amd/display: Fix fallback issues for DP LL 1.4a tests

Nawwar Ali (1):
  drm/amd/display: Update 709 gamma to 2.222 as stated in the standerd

Nicholas Kazlauskas (3):
  drm/amd/display: Update SR watermarks for DCN314
  drm/amd/display: Allow tuning DCN314 bounding box
  drm/amd/display: Fix reg timeout in enc314_enable_fifo

Paulo Miguel Almeida (2):
  drm/amdgpu: Replace 1-element array with flexible-array member
  drm/amdgpu: Replace one-element array with flex-array member

Philip Yang (2):
  drm/amdgpu: Unlock bo_list_mutex after error handling
  drm/amdgpu: Drop 

Re: Coverity: nouveau_dp_irq(): Null pointer dereferences

2022-11-11 Thread Kees Cook
On Fri, Nov 11, 2022 at 09:06:54PM +0100, Karol Herbst wrote:
> On Fri, Nov 11, 2022 at 8:21 PM Kees Cook  wrote:
> >
> > On Fri, Nov 11, 2022 at 11:13:17AM +0200, Jani Nikula wrote:
> > > On Thu, 10 Nov 2022, coverity-bot  wrote:
> > > > Hello!
> > > >
> > > > This is an experimental semi-automated report about issues detected by
> > > > Coverity from a scan of next-20221110 as part of the linux-next scan 
> > > > project:
> > > > https://scan.coverity.com/projects/linux-next-weekly-scan
> > > >
> > > > You're getting this email because you were associated with the 
> > > > identified
> > > > lines of code (noted below) that were touched by commits:
> > > >
> > > >   Mon Aug 31 19:10:08 2020 -0400
> > > > a0922278f83e ("drm/nouveau/kms/nv50-: Refactor and cleanup DP HPD 
> > > > handling")
> > >
> > > Hi Kees, this looks like a good idea, but maybe double check the Cc list
> > > generation? I was Cc'd on four mails today that I thought were
> > > irrelevant to me.
> >
> > Hi!
> >
> > Heh, I was recently asked to _expand_ the CC list. :)
> >
> > For these last pass of reports, I added a get_maintainers.pl run to the
> > identified commit. In this instance, the commit touched:
> >
> >  drivers/gpu/drm/nouveau/dispnv04/disp.c |6 +
> >  drivers/gpu/drm/nouveau/dispnv50/disp.c |  192 
> > ++--
> >  drivers/gpu/drm/nouveau/nouveau_connector.c |   14 ---
> >  drivers/gpu/drm/nouveau/nouveau_display.c   |2
> >  drivers/gpu/drm/nouveau/nouveau_display.h   |2
> >  drivers/gpu/drm/nouveau/nouveau_dp.c|  132 
> > -
> >  drivers/gpu/drm/nouveau/nouveau_encoder.h   |   33 +++-
> >  7 files changed, 244 insertions(+), 137 deletions(-)
> >
> > And the get_maintainers.pl rationale was:
> >
> > Ben Skeggs  (supporter:DRM DRIVER FOR NVIDIA 
> > GEFORCE/QUADRO 
> > GPUS,commit_signer:1/1=100%,commit_signer:6/16=38%,authored:4/16=25%,added_lines:23/124=19%,removed_lines:36/152=24%)
> > Karol Herbst  (supporter:DRM DRIVER FOR NVIDIA 
> > GEFORCE/QUADRO GPUS,commit_signer:2/1=100%)
> > Lyude Paul  (supporter:DRM DRIVER FOR NVIDIA 
> > GEFORCE/QUADRO 
> > GPUS,commit_signer:9/16=56%,authored:6/16=38%,added_lines:92/124=74%,removed_lines:107/152=70%)
> > David Airlie  (maintainer:DRM DRIVERS)
> > Daniel Vetter  (maintainer:DRM DRIVERS)
> > Ilia Mirkin  
> > (commit_signer:1/1=100%,authored:1/1=100%,added_lines:2/2=100%,removed_lines:2/2=100%)
> > "Nathan E. Egge"  (commit_signer:1/1=100%)
> > Jani Nikula  (commit_signer:6/16=38%)
> > Dave Airlie  (commit_signer:5/16=31%)
> > Thomas Zimmermann  
> > (commit_signer:4/16=25%,authored:4/16=25%)
> > dri-devel@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA 
> > GEFORCE/QUADRO GPUS)
> > nouv...@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA 
> > GEFORCE/QUADRO GPUS)
> >
> 
> I'd say it's good enough to message supporters and the mailing lists
> for at least Nouveau code, maybe even all drm drivers.

i.e. leave out the commit_signer hits?

> Not sure what to do about actual maintainers, but I doubt Dave and
> Daniel want to be CCed on every Coverity report here either.

I updated the CC logic based on this feedback:
https://lore.kernel.org/linux-hardening/87h6zgfub4@kernel.org/

So maybe just mailing lists?

-- 
Kees Cook


Re: Coverity: nouveau_dp_irq(): Null pointer dereferences

2022-11-11 Thread Karol Herbst
On Fri, Nov 11, 2022 at 8:21 PM Kees Cook  wrote:
>
> On Fri, Nov 11, 2022 at 11:13:17AM +0200, Jani Nikula wrote:
> > On Thu, 10 Nov 2022, coverity-bot  wrote:
> > > Hello!
> > >
> > > This is an experimental semi-automated report about issues detected by
> > > Coverity from a scan of next-20221110 as part of the linux-next scan 
> > > project:
> > > https://scan.coverity.com/projects/linux-next-weekly-scan
> > >
> > > You're getting this email because you were associated with the identified
> > > lines of code (noted below) that were touched by commits:
> > >
> > >   Mon Aug 31 19:10:08 2020 -0400
> > > a0922278f83e ("drm/nouveau/kms/nv50-: Refactor and cleanup DP HPD 
> > > handling")
> >
> > Hi Kees, this looks like a good idea, but maybe double check the Cc list
> > generation? I was Cc'd on four mails today that I thought were
> > irrelevant to me.
>
> Hi!
>
> Heh, I was recently asked to _expand_ the CC list. :)
>
> For these last pass of reports, I added a get_maintainers.pl run to the
> identified commit. In this instance, the commit touched:
>
>  drivers/gpu/drm/nouveau/dispnv04/disp.c |6 +
>  drivers/gpu/drm/nouveau/dispnv50/disp.c |  192 
> ++--
>  drivers/gpu/drm/nouveau/nouveau_connector.c |   14 ---
>  drivers/gpu/drm/nouveau/nouveau_display.c   |2
>  drivers/gpu/drm/nouveau/nouveau_display.h   |2
>  drivers/gpu/drm/nouveau/nouveau_dp.c|  132 
> -
>  drivers/gpu/drm/nouveau/nouveau_encoder.h   |   33 +++-
>  7 files changed, 244 insertions(+), 137 deletions(-)
>
> And the get_maintainers.pl rationale was:
>
> Ben Skeggs  (supporter:DRM DRIVER FOR NVIDIA 
> GEFORCE/QUADRO 
> GPUS,commit_signer:1/1=100%,commit_signer:6/16=38%,authored:4/16=25%,added_lines:23/124=19%,removed_lines:36/152=24%)
> Karol Herbst  (supporter:DRM DRIVER FOR NVIDIA 
> GEFORCE/QUADRO GPUS,commit_signer:2/1=100%)
> Lyude Paul  (supporter:DRM DRIVER FOR NVIDIA GEFORCE/QUADRO 
> GPUS,commit_signer:9/16=56%,authored:6/16=38%,added_lines:92/124=74%,removed_lines:107/152=70%)
> David Airlie  (maintainer:DRM DRIVERS)
> Daniel Vetter  (maintainer:DRM DRIVERS)
> Ilia Mirkin  
> (commit_signer:1/1=100%,authored:1/1=100%,added_lines:2/2=100%,removed_lines:2/2=100%)
> "Nathan E. Egge"  (commit_signer:1/1=100%)
> Jani Nikula  (commit_signer:6/16=38%)
> Dave Airlie  (commit_signer:5/16=31%)
> Thomas Zimmermann  
> (commit_signer:4/16=25%,authored:4/16=25%)
> dri-devel@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA 
> GEFORCE/QUADRO GPUS)
> nouv...@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA GEFORCE/QUADRO 
> GPUS)
>

I'd say it's good enough to message supporters and the mailing lists
for at least Nouveau code, maybe even all drm drivers.

Not sure what to do about actual maintainers, but I doubt Dave and
Daniel want to be CCed on every Coverity report here either.

Karol

>
> --
> Kees Cook
>



[PATCH] udmabuf: add vmap method to udmabuf_ops

2022-11-11 Thread Lukasz Wiecaszek
The reason behind that patch is associated with videobuf2 subsystem
(or more genrally with v4l2 framework) and user created
dma buffers (udmabuf). In some circumstances
when dealing with V4L2_MEMORY_DMABUF buffers videobuf2 subsystem
wants to use dma_buf_vmap() method on the attached dma buffer.
As udmabuf does not have .vmap operation implemented,
such dma_buf_vmap() natually fails.

videobuf2_common: [cap-3473b2f1] __vb2_queue_alloc: allocated 3 
buffers, 1 plane(s) each
videobuf2_common: [cap-3473b2f1] __prepare_dmabuf: buffer for plane 0 
changed
videobuf2_common: [cap-3473b2f1] __prepare_dmabuf: failed to map dmabuf 
for plane 0
videobuf2_common: [cap-3473b2f1] __buf_prepare: buffer preparation 
failed: -14

The patch itself seems to be strighforward.
It adds implementation of .vmap method to 'struct dma_buf_ops udmabuf_ops'.
.vmap method itself uses vm_map_ram() to map pages linearly
into the kernel virtual address space (only if such mapping
hasn't been created yet).

Signed-off-by: Lukasz Wiecaszek 
---
 drivers/dma-buf/udmabuf.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 2bcdb935a3ac..8649fcbd05c4 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static int list_limit = 1024;
 module_param(list_limit, int, 0644);
@@ -26,6 +27,7 @@ struct udmabuf {
struct page **pages;
struct sg_table *sg;
struct miscdevice *device;
+   void *vaddr;
 };
 
 static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
@@ -57,6 +59,21 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
return 0;
 }
 
+static int vmap_udmabuf(struct dma_buf *buf, struct dma_buf_map *map)
+{
+   struct udmabuf *ubuf = buf->priv;
+
+   if (!ubuf->vaddr) {
+   ubuf->vaddr = vm_map_ram(ubuf->pages, ubuf->pagecount, -1);
+   if (!ubuf->vaddr)
+   return -EINVAL;
+   }
+
+   dma_buf_map_set_vaddr(map, ubuf->vaddr);
+
+   return 0;
+}
+
 static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 enum dma_data_direction direction)
 {
@@ -159,6 +176,7 @@ static const struct dma_buf_ops udmabuf_ops = {
.unmap_dma_buf = unmap_udmabuf,
.release   = release_udmabuf,
.mmap  = mmap_udmabuf,
+   .vmap  = vmap_udmabuf,
.begin_cpu_access  = begin_cpu_udmabuf,
.end_cpu_access= end_cpu_udmabuf,
 };
-- 
2.25.1



Re: [PATCH printk v3 00/40] reduce console_lock scope

2022-11-11 Thread Mathieu Desnoyers

On 2022-11-07 09:15, John Ogness wrote:
[...]


The base commit for this series is from Paul McKenney's RCU tree
and provides an NMI-safe SRCU implementation [1]. Without the
NMI-safe SRCU implementation, this series is not less safe than
mainline. But we will need the NMI-safe SRCU implementation for
atomic consoles anyway, so we might as well get it in
now. Especially since it _does_ increase the reliability for
mainline in the panic path.


So, your email got me to review the SRCU nmi-safe series:

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git/log/?h=srcunmisafe.2022.10.21a

Especially this commit:

https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git/commit/?h=srcunmisafe.2022.10.21a=5d0f5953b60f5f7a278085b55ddc73e2932f4c33

I disagree with the overall approach taken there, which is to create
yet another SRCU flavor, this time with explicit "nmi-safe" read-locks.
This adds complexity to the kernel APIs and I think we can be clever
about this and make SRCU nmi-safe without requiring a whole new incompatible
API.

You can find the basic idea needed to achieve this in the libside RCU
user-space implementation. I needed to introduce a split-counter concept
to support rseq vs atomics to keep track of per-cpu grace period counters.
The "rseq" counter is the fast-path, but if rseq fails, the abort handler
uses the atomic counter instead.

https://github.com/compudj/side/blob/main/src/rcu.h#L23

struct side_rcu_percpu_count {
uintptr_t begin;
uintptr_t rseq_begin;
uintptr_t end;
uintptr_t rseq_end;
}  __attribute__((__aligned__(SIDE_CACHE_LINE_SIZE)));

The idea is to "split" each percpu counter into two counters, one for rseq,
and the other for atomics. When a grace period wants to observe the value of
a percpu counter, it simply sums the two counters:

https://github.com/compudj/side/blob/main/src/rcu.c#L112

The same idea can be applied to SRCU in the kernel: one counter for percpu ops,
and the other counter for nmi context, so basically:

srcu_read_lock()

if (likely(!in_nmi()))
  increment the percpu-ops lock counter
else
  increment the atomic lock counter

srcu_read_unlock()

if (likely(!in_nmi()))
  increment the percpu-ops unlock counter
else
  increment the atomic unlock counter

Then in the grace period sum the percpu-ops and the atomic values whenever
each counter value is read.

This would allow SRCU to be NMI-safe without requiring the callers to
explicitly state whether they need to be nmi-safe or not, and would only
take the overhead of the atomics in the NMI handlers rather than for all
users which happen to use SRCU read locks shared with nmi handlers.

Thoughts ?

Thanks,

Mathieu

--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com



Re: Coverity: nouveau_dp_irq(): Null pointer dereferences

2022-11-11 Thread Kees Cook
On Fri, Nov 11, 2022 at 11:13:17AM +0200, Jani Nikula wrote:
> On Thu, 10 Nov 2022, coverity-bot  wrote:
> > Hello!
> >
> > This is an experimental semi-automated report about issues detected by
> > Coverity from a scan of next-20221110 as part of the linux-next scan 
> > project:
> > https://scan.coverity.com/projects/linux-next-weekly-scan
> >
> > You're getting this email because you were associated with the identified
> > lines of code (noted below) that were touched by commits:
> >
> >   Mon Aug 31 19:10:08 2020 -0400
> > a0922278f83e ("drm/nouveau/kms/nv50-: Refactor and cleanup DP HPD 
> > handling")
> 
> Hi Kees, this looks like a good idea, but maybe double check the Cc list
> generation? I was Cc'd on four mails today that I thought were
> irrelevant to me.

Hi!

Heh, I was recently asked to _expand_ the CC list. :)

For these last pass of reports, I added a get_maintainers.pl run to the
identified commit. In this instance, the commit touched:

 drivers/gpu/drm/nouveau/dispnv04/disp.c |6 +
 drivers/gpu/drm/nouveau/dispnv50/disp.c |  192 
++--
 drivers/gpu/drm/nouveau/nouveau_connector.c |   14 ---
 drivers/gpu/drm/nouveau/nouveau_display.c   |2 
 drivers/gpu/drm/nouveau/nouveau_display.h   |2 
 drivers/gpu/drm/nouveau/nouveau_dp.c|  132 
-
 drivers/gpu/drm/nouveau/nouveau_encoder.h   |   33 +++-
 7 files changed, 244 insertions(+), 137 deletions(-)

And the get_maintainers.pl rationale was:

Ben Skeggs  (supporter:DRM DRIVER FOR NVIDIA GEFORCE/QUADRO 
GPUS,commit_signer:1/1=100%,commit_signer:6/16=38%,authored:4/16=25%,added_lines:23/124=19%,removed_lines:36/152=24%)
Karol Herbst  (supporter:DRM DRIVER FOR NVIDIA 
GEFORCE/QUADRO GPUS,commit_signer:2/1=100%)
Lyude Paul  (supporter:DRM DRIVER FOR NVIDIA GEFORCE/QUADRO 
GPUS,commit_signer:9/16=56%,authored:6/16=38%,added_lines:92/124=74%,removed_lines:107/152=70%)
David Airlie  (maintainer:DRM DRIVERS)
Daniel Vetter  (maintainer:DRM DRIVERS)
Ilia Mirkin  
(commit_signer:1/1=100%,authored:1/1=100%,added_lines:2/2=100%,removed_lines:2/2=100%)
"Nathan E. Egge"  (commit_signer:1/1=100%)
Jani Nikula  (commit_signer:6/16=38%)
Dave Airlie  (commit_signer:5/16=31%)
Thomas Zimmermann  
(commit_signer:4/16=25%,authored:4/16=25%)
dri-devel@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA GEFORCE/QUADRO 
GPUS)
nouv...@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA GEFORCE/QUADRO 
GPUS)


-- 
Kees Cook


[linux-next:master] BUILD REGRESSION f8f60f322f0640c8edda2942ca5f84b7a27c417a

2022-11-11 Thread kernel test robot
tree/branch: 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: f8f60f322f0640c8edda2942ca5f84b7a27c417a  Add linux-next specific 
files for 2022

Error/Warning reports:

https://lore.kernel.org/linux-mm/202210261404.b6ulzg7h-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202210270637.q5y7fikj-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202211090634.ryfkk0ws-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202211102047.qp7ithm4-...@intel.com
https://lore.kernel.org/oe-kbuild-all/20221624.1xztuzhj-...@intel.com

Error/Warning: (recently discovered and may have been fixed)

arch/arm/mach-s3c/devs.c:32:10: fatal error: linux/platform_data/dma-s3c24xx.h: 
No such file or directory
arch/x86/platform/efi/runtime-map.c:138:5: warning: no previous prototype for 
'efi_get_runtime_map_size' [-Wmissing-prototypes]
arch/x86/platform/efi/runtime-map.c:143:5: warning: no previous prototype for 
'efi_get_runtime_map_desc_size' [-Wmissing-prototypes]
arch/x86/platform/efi/runtime-map.c:148:5: warning: no previous prototype for 
'efi_runtime_map_copy' [-Wmissing-prototypes]
csky-linux-ld: local_object.c:(.text+0x84): undefined reference to 
`ipv6_icmp_error'
drivers/block/zram/zram_drv.c:1857:7: warning: variable 'err' is used 
uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
drivers/block/zram/zram_drv.c:1857:7: warning: variable 'err' is used 
uninitialized whenever '||' condition is true [-Wsometimes-uninitialized]
drivers/firmware/efi/memmap.c:57:52: warning: suggest braces around empty body 
in an 'if' statement [-Wempty-body]
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc.c:4887: warning: This comment 
starts with '/**', but isn't a kernel-doc comment. Refer 
Documentation/doc-guide/kernel-doc.rst
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link_dp.c:5073:24: warning: 
implicit conversion from 'enum ' to 'enum dc_status' 
[-Wenum-conversion]
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c:451:1: warning: no previous 
prototype for 'gf100_fifo_nonstall_block' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c:451:1: warning: no previous 
prototype for function 'gf100_fifo_nonstall_block' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c:34:1: warning: no previous 
prototype for 'nvkm_engn_cgrp_get' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c:34:1: warning: no previous 
prototype for function 'nvkm_engn_cgrp_get' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c:210:1: warning: no previous 
prototype for 'tu102_gr_load' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c:210:1: warning: no previous 
prototype for function 'tu102_gr_load' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c:49:1: warning: no previous prototype 
for 'wpr_generic_header_dump' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c:49:1: warning: no previous prototype 
for function 'wpr_generic_header_dump' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c:221:21: warning: variable 'loc' 
set but not used [-Wunused-but-set-variable]
local_object.c:(.text+0x60): undefined reference to `ipv6_icmp_error'
vmlinux.o: warning: objtool: __btrfs_map_block+0x1e22: unreachable instruction

Unverified Error/Warning (likely false positive, please contact us if 
interested):

drivers/gpu/drm/nouveau/nvkm/subdev/mc/ga100.c:51:1: sparse: sparse: symbol 
'ga100_mc_device' was not declared. Should it be static?
lib/zstd/compress/huf_compress.c:460 HUF_getIndex() warn: the 
'RANK_POSITION_LOG_BUCKETS_BEGIN' macro might need parens
lib/zstd/decompress/zstd_decompress_block.c:1009 ZSTD_execSequence() warn: 
inconsistent indenting
lib/zstd/decompress/zstd_decompress_block.c:894 ZSTD_execSequenceEnd() warn: 
inconsistent indenting
lib/zstd/decompress/zstd_decompress_block.c:942 
ZSTD_execSequenceEndSplitLitBuffer() warn: inconsistent indenting
lib/zstd/decompress/zstd_decompress_internal.h:206 ZSTD_DCtx_get_bmi2() warn: 
inconsistent indenting
mm/khugepaged.c:2038 collapse_file() warn: iterator used outside loop: 'page'

Error/Warning ids grouped by kconfigs:

gcc_recent_errors
|-- alpha-allyesconfig
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-fifo-gf100.c:warning:no-previous-prototype-for-gf100_fifo_nonstall_block
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-fifo-runl.c:warning:no-previous-prototype-for-nvkm_engn_cgrp_get
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-gr-tu102.c:warning:no-previous-prototype-for-tu102_gr_load
|   |-- 
drivers-gpu-drm-nouveau-nvkm-nvfw-acr.c:warning:no-previous-prototype-for-wpr_generic_header_dump
|   `-- 
drivers-gpu-drm-nouveau-nvkm-subdev-acr-lsfw.c:warning:variable-loc-set-but-not-used
|-- alpha-randconfig-r003-2022
|   |-- 
drivers-gpu-drm-amd-amdgpu

Re: [PATCH] drm/virtio: Fix memory leak in virtio_gpu_object_create()

2022-11-11 Thread Dmitry Osipenko
On 11/9/22 12:19, Xiu Jianfeng wrote:
> The virtio_gpu_object_shmem_init() will alloc memory and save it in
> @ents, so when virtio_gpu_array_alloc() fails, this memory should be
> freed, this patch fixes it.
> 
> Fixes: e7fef0923303 ("drm/virtio: Simplify error handling of 
> virtio_gpu_object_create()")
> Signed-off-by: Xiu Jianfeng 
> ---
>  drivers/gpu/drm/virtio/virtgpu_object.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c 
> b/drivers/gpu/drm/virtio/virtgpu_object.c
> index 8d7728181de0..c7e74cf13022 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_object.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_object.c
> @@ -184,7 +184,7 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
> *vgdev,
>   struct virtio_gpu_object_array *objs = NULL;
>   struct drm_gem_shmem_object *shmem_obj;
>   struct virtio_gpu_object *bo;
> - struct virtio_gpu_mem_entry *ents;
> + struct virtio_gpu_mem_entry *ents = NULL;
>   unsigned int nents;
>   int ret;
>  
> @@ -210,7 +210,7 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
> *vgdev,
>   ret = -ENOMEM;
>   objs = virtio_gpu_array_alloc(1);
>   if (!objs)
> - goto err_put_id;
> + goto err_free_entry;
>   virtio_gpu_array_add_obj(objs, >base.base);
>  
>   ret = virtio_gpu_array_lock_resv(objs);
> @@ -239,6 +239,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
> *vgdev,
>  
>  err_put_objs:
>   virtio_gpu_array_put_free(objs);
> +err_free_entry:
> + kvfree(ents);
>  err_put_id:
>   virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle);
>  err_free_gem:

Reviewed-by: Dmitry Osipenko 

-- 
Best regards,
Dmitry



Re: [git pull] drm fixes for 6.1-rc5

2022-11-11 Thread pr-tracker-bot
The pull request you sent on Fri, 11 Nov 2022 12:18:21 +1000:

> git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2022-11-11

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/fd979ca691715891a979ce12d1a485b108af74d3

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


Re: [PATCH v3 2/2] drm/bridge: anx7625: register content protect property

2022-11-11 Thread Sean Paul
On Wed, Nov 02, 2022 at 07:11:47PM +0800, Hsin-Yi Wang wrote:
> Set support_hdcp so the connector can register content protect proterty
> when it's initializing.
> 

Reviewed-by: Sean Paul 

> Signed-off-by: Hsin-Yi Wang 
> ---
>  drivers/gpu/drm/bridge/analogix/anx7625.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
> b/drivers/gpu/drm/bridge/analogix/anx7625.c
> index b0ff1ecb80a50..0636ac59c7399 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> @@ -2680,6 +2680,7 @@ static int anx7625_i2c_probe(struct i2c_client *client,
>   platform->bridge.type = platform->pdata.panel_bridge ?
>   DRM_MODE_CONNECTOR_eDP :
>   DRM_MODE_CONNECTOR_DisplayPort;
> + platform->bridge.support_hdcp = true;
>  
>   drm_bridge_add(>bridge);
>  
> -- 
> 2.38.0.135.g90850a2211-goog
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v3 1/2] drm_bridge: register content protect property

2022-11-11 Thread Sean Paul
On Wed, Nov 02, 2022 at 07:11:46PM +0800, Hsin-Yi Wang wrote:
> Some bridges are able to update HDCP status from userspace request if
> they support HDCP.
> 
> HDCP property is the same as other connector properties that needs to be
> created after the connecter is initialized and before the connector is
> registered.
> 
> If there exists a bridge that supports HDCP, add the property to the
> bridge connector.
> 

Reviewed-by: Sean Paul 

> Signed-off-by: Hsin-Yi Wang 
> ---
> v2->v3:
> Only register the property when there exists any bridge that supports
> hdcp.
> ---
>  drivers/gpu/drm/drm_bridge_connector.c | 8 
>  include/drm/drm_bridge.h   | 4 
>  2 files changed, 12 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_bridge_connector.c 
> b/drivers/gpu/drm/drm_bridge_connector.c
> index 1c7d936523df5..b4fb5da0b963f 100644
> --- a/drivers/gpu/drm/drm_bridge_connector.c
> +++ b/drivers/gpu/drm/drm_bridge_connector.c
> @@ -7,6 +7,7 @@
>  #include 
>  #include 
>  
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -333,6 +334,7 @@ struct drm_connector *drm_bridge_connector_init(struct 
> drm_device *drm,
>   struct i2c_adapter *ddc = NULL;
>   struct drm_bridge *bridge, *panel_bridge = NULL;
>   int connector_type;
> + bool support_hdcp = false;
>  
>   bridge_connector = kzalloc(sizeof(*bridge_connector), GFP_KERNEL);
>   if (!bridge_connector)
> @@ -376,6 +378,9 @@ struct drm_connector *drm_bridge_connector_init(struct 
> drm_device *drm,
>  
>   if (drm_bridge_is_panel(bridge))
>   panel_bridge = bridge;
> +
> + if (bridge->support_hdcp)
> + support_hdcp = true;
>   }
>  
>   if (connector_type == DRM_MODE_CONNECTOR_Unknown) {
> @@ -398,6 +403,9 @@ struct drm_connector *drm_bridge_connector_init(struct 
> drm_device *drm,
>   if (panel_bridge)
>   drm_panel_bridge_set_orientation(connector, panel_bridge);
>  
> + if (support_hdcp && IS_ENABLED(CONFIG_DRM_DISPLAY_HDCP_HELPER))
> + drm_connector_attach_content_protection_property(connector, 
> true);
> +
>   return connector;
>  }
>  EXPORT_SYMBOL_GPL(drm_bridge_connector_init);
> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> index 6b65b0dfb4fb4..1d2ab70f3436a 100644
> --- a/include/drm/drm_bridge.h
> +++ b/include/drm/drm_bridge.h
> @@ -768,6 +768,10 @@ struct drm_bridge {
>* modes.
>*/
>   bool interlace_allowed;
> + /**
> +  * @support_hdcp: Indicate that the bridge supports HDCP.
> +  */
> + bool support_hdcp;
>   /**
>* @ddc: Associated I2C adapter for DDC access, if any.
>*/
> -- 
> 2.38.0.135.g90850a2211-goog
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


[PATCH i-g-t 8/8] gputop: Basic vendor agnostic GPU top tool

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Rudimentary vendor agnostic example of how lib_igt_drm_clients can be used
to display a sorted by card and usage list of processes using GPUs.

Borrows a bit of code from intel_gpu_top but for now omits the fancy
features like interactive functionality, card selection, client
aggregation, sort modes, JSON output  and pretty engine names. Also no
support for global GPU or system metrics.

On the other hand it shows clients from all DRM cards which
intel_gpu_top does not do.

Signed-off-by: Tvrtko Ursulin 
Cc: Rob Clark 
Cc: Christian König 
Acked-by: Christian König 
---
 tools/gputop.c| 260 ++
 tools/meson.build |   5 +
 2 files changed, 265 insertions(+)
 create mode 100644 tools/gputop.c

diff --git a/tools/gputop.c b/tools/gputop.c
new file mode 100644
index ..d259cac1ab17
--- /dev/null
+++ b/tools/gputop.c
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "igt_drm_clients.h"
+#include "igt_drm_fdinfo.h"
+
+static const char *bars[] = { " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█" };
+
+static void n_spaces(const unsigned int n)
+{
+   unsigned int i;
+
+   for (i = 0; i < n; i++)
+   putchar(' ');
+}
+
+static void print_percentage_bar(double percent, int max_len)
+{
+   int bar_len, i, len = max_len - 2;
+   const int w = 8;
+
+   assert(max_len > 0);
+
+   bar_len = ceil(w * percent * len / 100.0);
+   if (bar_len > w * len)
+   bar_len = w * len;
+
+   putchar('|');
+
+   for (i = bar_len; i >= w; i -= w)
+   printf("%s", bars[w]);
+   if (i)
+   printf("%s", bars[i]);
+
+   len -= (bar_len + (w - 1)) / w;
+   n_spaces(len);
+
+   putchar('|');
+}
+
+static int
+print_client_header(struct igt_drm_client *c, int lines, int con_w, int con_h,
+   int *engine_w)
+{
+   const char *pidname = "PID   NAME ";
+   int ret, len = strlen(pidname);
+
+   if (lines++ >= con_h || len >= con_w)
+   return lines;
+   printf("\033[7m");
+   ret = printf("DRM minor %u", c->drm_minor);
+   n_spaces(con_w - ret);
+
+   if (lines++ >= con_h)
+   return lines;
+   printf("\n%s", pidname);
+
+   if (c->engines->num_engines) {
+   unsigned int i;
+   int width;
+
+   *engine_w = width = (con_w - len) / c->engines->num_engines;
+
+   for (i = 0; i <= c->engines->max_engine_id; i++) {
+   const char *name = c->engines->names[i];
+   int name_len = strlen(name);
+   int pad = (width - name_len) / 2;
+   int spaces = width - pad - name_len;
+
+   if (!name)
+   continue;
+
+   if (pad < 0 || spaces < 0)
+   continue;
+
+   n_spaces(pad);
+   printf("%s", name);
+   n_spaces(spaces);
+   len += pad + name_len + spaces;
+   }
+   }
+
+   n_spaces(con_w - len);
+   printf("\033[0m\n");
+
+   return lines;
+}
+
+
+static bool
+newheader(const struct igt_drm_client *c, const struct igt_drm_client *pc)
+{
+   return !pc || c->drm_minor != pc->drm_minor;
+}
+
+static int
+print_client(struct igt_drm_client *c, struct igt_drm_client **prevc,
+double t, int lines, int con_w, int con_h,
+unsigned int period_us, int *engine_w)
+{
+   unsigned int i;
+
+   /* Filter out idle clients. */
+   if (!c->total_runtime || c->samples < 2)
+   return lines;
+
+   /* Print header when moving to a different DRM card. */
+   if (newheader(c, *prevc)) {
+   lines = print_client_header(c, lines, con_w, con_h, engine_w);
+   if (lines >= con_h)
+   return lines;
+   }
+
+   *prevc = c;
+
+   printf("%8u %17s ", c->pid, c->print_name);
+   lines++;
+
+   for (i = 0; c->samples > 1 && i <= c->engines->max_engine_id; i++) {
+   double pct;
+
+   if (!c->engines->capacity[i])
+   continue;
+
+   pct = (double)c->val[i] / period_us / 1e3 * 100 /
+ c->engines->capacity[i];
+
+   /*
+* Guard against fluctuations between our scanning period and
+* GPU times as exported by the kernel in fdinfo.
+*/
+   if (pct > 100.0)
+   pct = 100.0;
+
+   print_percentage_bar(pct, 

[PATCH i-g-t 7/8] libdrmclient: Enforce client status sort order in the library

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Some libdrmclient operations require that inactive clients are last in the
list. Rather than relying on callers of the library sort routine to
implement their comparison callbacks correctly, enforce this order
directly in the library and let callers comparison callbacks concern
themselves only with ordering they are interested in.

Signed-off-by: Tvrtko Ursulin 
---
 lib/igt_drm_clients.c | 37 +++-
 lib/igt_drm_clients.h |  2 +-
 tools/intel_gpu_top.c | 81 +++
 3 files changed, 65 insertions(+), 55 deletions(-)

diff --git a/lib/igt_drm_clients.c b/lib/igt_drm_clients.c
index d507c07fec87..b3eda39cd226 100644
--- a/lib/igt_drm_clients.c
+++ b/lib/igt_drm_clients.c
@@ -191,22 +191,38 @@ void igt_drm_client_free(struct igt_drm_client *c, bool 
clear)
memset(c, 0, sizeof(*c));
 }
 
+struct sort_context
+{
+   int (*user_cmp)(const void *, const void *, void *);
+};
+
+static int sort_cmp(const void *_a, const void *_b, void *_ctx)
+{
+   const struct sort_context *ctx = _ctx;
+   const struct igt_drm_client *a = _a;
+   const struct igt_drm_client *b = _b;
+   int cmp = b->status - a->status;
+
+   if (cmp == 0)
+   return ctx->user_cmp(_a, _b, _ctx);
+   else
+   return cmp;
+}
+
 /**
  * igt_drm_clients_sort:
  * @clients: Previously initialised clients object
  * @cmp: Client comparison callback
  *
  * Sort the clients array according to the passed in comparison callback which
- * is compatible with the qsort(3) semantics.
- *
- * Caller has to ensure the callback is putting all active
- * (IGT_DRM_CLIENT_ALIVE) clients in a single group at the head of the array
- * before any other sorting criteria.
+ * is compatible with the qsort(3) semantics, with the third void * argument
+ * being unused.
  */
 struct igt_drm_clients *
 igt_drm_clients_sort(struct igt_drm_clients *clients,
-int (*cmp)(const void *, const void *))
+int (*cmp)(const void *, const void *, void *))
 {
+   struct sort_context ctx = { .user_cmp = cmp };
unsigned int active, free;
struct igt_drm_client *c;
int tmp;
@@ -214,8 +230,13 @@ igt_drm_clients_sort(struct igt_drm_clients *clients,
if (!clients)
return clients;
 
-   qsort(clients->client, clients->num_clients, sizeof(*clients->client),
- cmp);
+   /*
+* Enforce client->status ordering (active followed by free) by running
+* the user provided comparison callback wrapped in the one internal
+* to the library.
+*/
+   qsort_r(clients->client, clients->num_clients, sizeof(*clients->client),
+ sort_cmp, );
 
/* Trim excessive array space. */
active = 0;
diff --git a/lib/igt_drm_clients.h b/lib/igt_drm_clients.h
index 0a903b431eaa..df8022d42098 100644
--- a/lib/igt_drm_clients.h
+++ b/lib/igt_drm_clients.h
@@ -82,6 +82,6 @@ igt_drm_clients_scan(struct igt_drm_clients *clients,
 
 struct igt_drm_clients *
 igt_drm_clients_sort(struct igt_drm_clients *clients,
-int (*cmp)(const void *, const void *));
+int (*cmp)(const void *, const void *, void *));
 
 #endif /* IGT_DRM_CLIENTS_H */
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
index e92a7fb69b48..d931e96e8ee2 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -674,85 +674,74 @@ static void pmu_sample(struct engines *engines)
}
 }
 
-static int client_last_cmp(const void *_a, const void *_b)
+static int
+__client_id_cmp(const struct igt_drm_client *a,
+   const struct igt_drm_client *b)
+{
+   if (a->id > b->id)
+   return 1;
+   else if (a->id < b->id)
+   return -1;
+   else
+   return 0;
+}
+
+static int client_last_cmp(const void *_a, const void *_b, void *unused)
 {
const struct igt_drm_client *a = _a;
const struct igt_drm_client *b = _b;
-   long tot_a, tot_b;
+   long val_a = a->last_runtime, val_b = b->last_runtime;
 
/*
 * Sort clients in descending order of runtime in the previous sampling
-* period for active ones, followed by inactive. Tie-breaker is client
-* id.
+* period. Tie-breaker is client id.
 */
 
-   tot_a = a->status == IGT_DRM_CLIENT_ALIVE ? a->last_runtime : -1;
-   tot_b = b->status == IGT_DRM_CLIENT_ALIVE ? b->last_runtime : -1;
-
-   tot_b -= tot_a;
-   if (tot_b > 0)
+   if (val_a == val_b)
+   return __client_id_cmp(a, b);
+   else if (val_b > val_a)
return 1;
-   if (tot_b < 0)
+   else
return -1;
-
-   return (int)b->id - a->id;
 }
 
-static int client_total_cmp(const void *_a, const void *_b)
+static int client_total_cmp(const void *_a, const void *_b, void *unused)
 {
const struct igt_drm_client 

[PATCH i-g-t 5/8] libdrmfdinfo: Track largest engine index

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Prep code for incoming work.

Signed-off-by: Tvrtko Ursulin 
---
 lib/igt_drm_fdinfo.c | 2 ++
 lib/igt_drm_fdinfo.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/lib/igt_drm_fdinfo.c b/lib/igt_drm_fdinfo.c
index 68c89ad2c17e..b850d2210ae7 100644
--- a/lib/igt_drm_fdinfo.c
+++ b/lib/igt_drm_fdinfo.c
@@ -162,6 +162,8 @@ __igt_parse_drm_fdinfo(int dir, const char *fd, struct 
drm_client_fdinfo *info,
info->capacity[idx] = 1;
info->busy[idx] = val;
info->num_engines++;
+   if (idx > info->last_engine_index)
+   info->last_engine_index = idx;
}
} else if (!strncmp(l, "drm-engine-capacity-", 20)) {
idx = parse_engine(l, info,
diff --git a/lib/igt_drm_fdinfo.h b/lib/igt_drm_fdinfo.h
index fa4982f4030e..6284e05e868a 100644
--- a/lib/igt_drm_fdinfo.h
+++ b/lib/igt_drm_fdinfo.h
@@ -38,6 +38,7 @@ struct drm_client_fdinfo {
unsigned long id;
 
unsigned int num_engines;
+   unsigned int last_engine_index;
unsigned int capacity[DRM_CLIENT_FDINFO_MAX_ENGINES];
char names[DRM_CLIENT_FDINFO_MAX_ENGINES][256];
uint64_t busy[DRM_CLIENT_FDINFO_MAX_ENGINES];
-- 
2.34.1



[PATCH i-g-t 3/8] libdrmclients: Record client drm minor

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Prepare for supporting clients belonging to multiple DRM cards by storing
the DRM minor in the client record.

Signed-off-by: Tvrtko Ursulin 
---
 lib/igt_drm_clients.c | 22 ++
 lib/igt_drm_clients.h |  1 +
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/lib/igt_drm_clients.c b/lib/igt_drm_clients.c
index eabd43773f2d..c23a3fae9793 100644
--- a/lib/igt_drm_clients.c
+++ b/lib/igt_drm_clients.c
@@ -115,7 +115,7 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned 
int pid, char *name,
 static void
 igt_drm_client_add(struct igt_drm_clients *clients,
   const struct drm_client_fdinfo *info,
-  unsigned int pid, char *name)
+  unsigned int pid, char *name, unsigned int drm_minor)
 {
struct igt_drm_client *c;
 
@@ -140,6 +140,7 @@ igt_drm_client_add(struct igt_drm_clients *clients,
}
 
c->id = info->id;
+   c->drm_minor = drm_minor;
c->clients = clients;
c->val = calloc(clients->num_classes, sizeof(c->val));
c->last = calloc(clients->num_classes, sizeof(c->last));
@@ -286,16 +287,21 @@ static bool get_task_name(const char *buffer, char *out, 
unsigned long sz)
return true;
 }
 
-static bool is_drm_fd(int fd_dir, const char *name)
+static bool is_drm_fd(int fd_dir, const char *name, unsigned int *minor)
 {
struct stat stat;
int ret;
 
ret = fstatat(fd_dir, name, , 0);
 
-   return ret == 0 &&
-  (stat.st_mode & S_IFMT) == S_IFCHR &&
-  major(stat.st_rdev) == 226;
+   if (ret == 0 &&
+   (stat.st_mode & S_IFMT) == S_IFCHR &&
+   major(stat.st_rdev) == 226) {
+   *minor = minor(stat.st_rdev);
+   return true;
+   }
+
+   return false;
 }
 
 /**
@@ -348,10 +354,10 @@ igt_drm_clients_scan(struct igt_drm_clients *clients,
return clients;
 
while ((proc_dent = readdir(proc_dir)) != NULL) {
+   unsigned int client_pid, minor = 0;
int pid_dir = -1, fd_dir = -1;
struct dirent *fdinfo_dent;
char client_name[64] = { };
-   unsigned int client_pid;
DIR *fdinfo_dir = NULL;
char buf[4096];
size_t count;
@@ -393,7 +399,7 @@ igt_drm_clients_scan(struct igt_drm_clients *clients,
if (!isdigit(fdinfo_dent->d_name[0]))
continue;
 
-   if (!is_drm_fd(fd_dir, fdinfo_dent->d_name))
+   if (!is_drm_fd(fd_dir, fdinfo_dent->d_name, ))
continue;
 
if (!__igt_parse_drm_fdinfo(dirfd(fdinfo_dir),
@@ -412,7 +418,7 @@ igt_drm_clients_scan(struct igt_drm_clients *clients,
info.id);
if (!c)
igt_drm_client_add(clients, , client_pid,
-  client_name);
+  client_name, minor);
else
igt_drm_client_update(c, client_pid,
  client_name, );
diff --git a/lib/igt_drm_clients.h b/lib/igt_drm_clients.h
index bced19adb055..ffa219c9c9fd 100644
--- a/lib/igt_drm_clients.h
+++ b/lib/igt_drm_clients.h
@@ -44,6 +44,7 @@ struct igt_drm_client {
 
enum igt_drm_client_status status;
unsigned int id; /* DRM client id from fdinfo. */
+   unsigned int drm_minor; /* DRM minor of this client. */
unsigned int pid; /* PID which has this DRM fd open. */
char name[24]; /* Process name of the owning PID. */
char print_name[24]; /* Name without any non-printable characters. */
-- 
2.34.1



[PATCH i-g-t 4/8] libdrmclient: Support multiple DRM cards

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Require DRM minor match during client lookup.

Signed-off-by: Tvrtko Ursulin 
---
 lib/igt_drm_clients.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/lib/igt_drm_clients.c b/lib/igt_drm_clients.c
index c23a3fae9793..e11c8b18188f 100644
--- a/lib/igt_drm_clients.c
+++ b/lib/igt_drm_clients.c
@@ -49,7 +49,7 @@ struct igt_drm_clients *igt_drm_clients_init(void 
*private_data)
 static struct igt_drm_client *
 igt_drm_clients_find(struct igt_drm_clients *clients,
 enum igt_drm_client_status status,
-unsigned int id)
+unsigned int drm_minor, unsigned int id)
 {
unsigned int start, num;
struct igt_drm_client *c;
@@ -61,7 +61,8 @@ igt_drm_clients_find(struct igt_drm_clients *clients,
if (status != c->status)
continue;
 
-   if (status == IGT_DRM_CLIENT_FREE || c->id == id)
+   if (status == IGT_DRM_CLIENT_FREE ||
+   (drm_minor == c->drm_minor && c->id == id))
return c;
}
 
@@ -119,9 +120,10 @@ igt_drm_client_add(struct igt_drm_clients *clients,
 {
struct igt_drm_client *c;
 
-   assert(!igt_drm_clients_find(clients, IGT_DRM_CLIENT_ALIVE, info->id));
+   assert(!igt_drm_clients_find(clients, IGT_DRM_CLIENT_ALIVE,
+drm_minor, info->id));
 
-   c = igt_drm_clients_find(clients, IGT_DRM_CLIENT_FREE, 0);
+   c = igt_drm_clients_find(clients, IGT_DRM_CLIENT_FREE, 0, 0);
if (!c) {
unsigned int idx = clients->num_clients;
 
@@ -411,11 +413,11 @@ igt_drm_clients_scan(struct igt_drm_clients *clients,
continue;
 
if (igt_drm_clients_find(clients, IGT_DRM_CLIENT_ALIVE,
-   info.id))
+minor, info.id))
continue; /* Skip duplicate fds. */
 
c = igt_drm_clients_find(clients, IGT_DRM_CLIENT_PROBE,
-   info.id);
+minor, info.id);
if (!c)
igt_drm_client_add(clients, , client_pid,
   client_name, minor);
-- 
2.34.1



[PATCH i-g-t 6/8] libdrmclient/intel_gpu_top: Decouple hardcoded engine assumptions

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Intel_gpu_top gets it's main engine configuration data via PMU probe and
uses that for per client view as well. Furthemore code so far assumed only
clients belonging from a single DRM card would be tracked in a single
clients list.

Break this inter-dependency by moving the engine data to be per client and
also have libdrmclient probe the engine configuration independently using
the previously added libdrmfdinfo facilities.

Signed-off-by: Tvrtko Ursulin 
---
 lib/igt_drm_clients.c |  38 +++--
 lib/igt_drm_clients.h |  14 ++---
 tools/intel_gpu_top.c | 127 +++---
 3 files changed, 134 insertions(+), 45 deletions(-)

diff --git a/lib/igt_drm_clients.c b/lib/igt_drm_clients.c
index e11c8b18188f..d507c07fec87 100644
--- a/lib/igt_drm_clients.c
+++ b/lib/igt_drm_clients.c
@@ -97,7 +97,7 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned int 
pid, char *name,
c->last_runtime = 0;
c->total_runtime = 0;
 
-   for (i = 0; i < c->clients->num_classes; i++) {
+   for (i = 0; i <= c->engines->max_engine_id; i++) {
assert(i < ARRAY_SIZE(info->busy));
 
if (info->busy[i] < c->last[i])
@@ -119,6 +119,7 @@ igt_drm_client_add(struct igt_drm_clients *clients,
   unsigned int pid, char *name, unsigned int drm_minor)
 {
struct igt_drm_client *c;
+   unsigned int i;
 
assert(!igt_drm_clients_find(clients, IGT_DRM_CLIENT_ALIVE,
 drm_minor, info->id));
@@ -144,8 +145,28 @@ igt_drm_client_add(struct igt_drm_clients *clients,
c->id = info->id;
c->drm_minor = drm_minor;
c->clients = clients;
-   c->val = calloc(clients->num_classes, sizeof(c->val));
-   c->last = calloc(clients->num_classes, sizeof(c->last));
+   c->engines = malloc(sizeof(*c->engines));
+   assert(c->engines);
+   memset(c->engines, 0, sizeof(*c->engines));
+   c->engines->capacity = calloc(info->last_engine_index + 1,
+ sizeof(*c->engines->capacity));
+   assert(c->engines->capacity);
+   c->engines->names = calloc(info->last_engine_index + 1,
+  sizeof(*c->engines->names));
+   assert(c->engines->names);
+
+   for (i = 0; i <= info->last_engine_index; i++) {
+   if (!info->capacity[i])
+   continue;
+
+   c->engines->capacity[i] = info->capacity[i];
+   c->engines->names[i] = strdup(info->names[i]);
+   assert(c->engines->names[i]);
+   c->engines->num_engines++;
+   c->engines->max_engine_id = i;
+   }
+   c->val = calloc(c->engines->max_engine_id + 1, sizeof(c->val));
+   c->last = calloc(c->engines->max_engine_id + 1, sizeof(c->last));
assert(c->val && c->last);
 
igt_drm_client_update(c, pid, name, info);
@@ -154,6 +175,15 @@ igt_drm_client_add(struct igt_drm_clients *clients,
 static
 void igt_drm_client_free(struct igt_drm_client *c, bool clear)
 {
+   unsigned int i;
+
+   if (c->engines) {
+   for (i = 0; i <= c->engines->max_engine_id; i++)
+   free(c->engines->names[i]);
+   free(c->engines->capacity);
+   free(c->engines->names);
+   }
+   free(c->engines);
free(c->val);
free(c->last);
 
@@ -323,7 +353,7 @@ static bool is_drm_fd(int fd_dir, const char *name, 
unsigned int *minor)
  *
  * If @name_map is not provided engine names will be auto-detected (this is
  * less performant) and indices will correspond with auto-detected names as
- * listed int clients->engine_class[].
+ * listed int clients->engines->names[].
  */
 struct igt_drm_clients *
 igt_drm_clients_scan(struct igt_drm_clients *clients,
diff --git a/lib/igt_drm_clients.h b/lib/igt_drm_clients.h
index ffa219c9c9fd..0a903b431eaa 100644
--- a/lib/igt_drm_clients.h
+++ b/lib/igt_drm_clients.h
@@ -31,10 +31,12 @@ enum igt_drm_client_status {
IGT_DRM_CLIENT_PROBE
 };
 
-struct igt_drm_client_engine_class {
-   unsigned int engine_class;
-   const char *name;
-   unsigned int num_engines;
+struct igt_drm_client_engines {
+   unsigned int num_engines; /* Number of discovered active engines. */
+   unsigned int max_engine_id; /* Largest engine index discovered.
+  (Can differ from num_engines - 1 when 
using the engine map facility.) */
+   unsigned int *capacity; /* Array of engine capacities as parsed from 
fdinfo. */
+   char **names; /* Array of engine names, either auto-detected or from 
the passed in engine map. */
 };
 
 struct igt_drm_clients;
@@ -43,6 +45,7 @@ struct igt_drm_client {
struct igt_drm_clients *clients; /* Owning list. */
 
enum igt_drm_client_status status;
+   struct igt_drm_client_engines *engines; /* Engines used by this client, 
to map with 

[PATCH i-g-t 2/8] libdrmfdinfo: Allow specifying custom engine map

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Instead of hard coding the engine names, allow a map of names to indices
to either be passed in or it gets auto-detected (less efficient) while
parsing.
---
 lib/igt_drm_clients.c   | 18 +---
 lib/igt_drm_clients.h   |  3 ++-
 lib/igt_drm_fdinfo.c| 48 +++--
 lib/igt_drm_fdinfo.h| 15 ++---
 tests/i915/drm_fdinfo.c | 19 
 tools/intel_gpu_top.c   | 16 +++---
 6 files changed, 89 insertions(+), 30 deletions(-)

diff --git a/lib/igt_drm_clients.c b/lib/igt_drm_clients.c
index 45de2d0f1cc5..eabd43773f2d 100644
--- a/lib/igt_drm_clients.c
+++ b/lib/igt_drm_clients.c
@@ -302,14 +302,26 @@ static bool is_drm_fd(int fd_dir, const char *name)
  * igt_drm_clients_scan:
  * @clients: Previously initialised clients object
  * @filter_client: Callback for client filtering
+ * @name_map: Array of engine name strings
+ * @map_entries: Number of items in the @name_map array
  *
  * Scan all open file descriptors from all processes in order to find all DRM
  * clients and manage our internal list.
+ *
+ * If @name_map is provided each found engine in the fdinfo struct must
+ * correspond to one of the provided names. In this case the index of the 
engine
+ * stats tracked in struct igt_drm_client will be tracked under the same index
+ * as the engine name provided.
+ *
+ * If @name_map is not provided engine names will be auto-detected (this is
+ * less performant) and indices will correspond with auto-detected names as
+ * listed int clients->engine_class[].
  */
 struct igt_drm_clients *
 igt_drm_clients_scan(struct igt_drm_clients *clients,
 bool (*filter_client)(const struct igt_drm_clients *,
-  const struct drm_client_fdinfo *))
+  const struct drm_client_fdinfo *),
+const char **name_map, unsigned int map_entries)
 {
struct dirent *proc_dent;
struct igt_drm_client *c;
@@ -385,8 +397,8 @@ igt_drm_clients_scan(struct igt_drm_clients *clients,
continue;
 
if (!__igt_parse_drm_fdinfo(dirfd(fdinfo_dir),
-   fdinfo_dent->d_name,
-   ))
+   fdinfo_dent->d_name, ,
+   name_map, map_entries))
continue;
 
if (filter_client && !filter_client(clients, ))
diff --git a/lib/igt_drm_clients.h b/lib/igt_drm_clients.h
index 969793d5b51e..bced19adb055 100644
--- a/lib/igt_drm_clients.h
+++ b/lib/igt_drm_clients.h
@@ -76,7 +76,8 @@ void igt_drm_clients_free(struct igt_drm_clients *clients);
 struct igt_drm_clients *
 igt_drm_clients_scan(struct igt_drm_clients *clients,
 bool (*filter_client)(const struct igt_drm_clients *,
-  const struct drm_client_fdinfo *));
+  const struct drm_client_fdinfo *),
+const char **name_map, unsigned int map_entries);
 
 struct igt_drm_clients *
 igt_drm_clients_sort(struct igt_drm_clients *clients,
diff --git a/lib/igt_drm_fdinfo.c b/lib/igt_drm_fdinfo.c
index 250d9e8917f2..68c89ad2c17e 100644
--- a/lib/igt_drm_fdinfo.c
+++ b/lib/igt_drm_fdinfo.c
@@ -22,6 +22,7 @@
  *
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -53,14 +54,10 @@ static size_t read_fdinfo(char *buf, const size_t sz, int 
at, const char *name)
 }
 
 static int parse_engine(char *line, struct drm_client_fdinfo *info,
-   size_t prefix_len, uint64_t *val)
+   size_t prefix_len,
+   const char **name_map, unsigned int map_entries,
+   uint64_t *val)
 {
-   static const char *e2class[] = {
-   "render",
-   "copy",
-   "video",
-   "video-enhance",
-   };
ssize_t name_len;
char *name, *p;
int found = -1;
@@ -76,10 +73,26 @@ static int parse_engine(char *line, struct 
drm_client_fdinfo *info,
 
name = line + prefix_len;
 
-   for (i = 0; i < ARRAY_SIZE(e2class); i++) {
-   if (!strncmp(name, e2class[i], name_len)) {
-   found = i;
-   break;
+   if (name_map) {
+   for (i = 0; i < map_entries; i++) {
+   if (!strncmp(name, name_map[i], name_len)) {
+   found = i;
+   break;
+   }
+   }
+   } else {
+   for (i = 0; i < info->num_engines; i++) {
+   if (!strncmp(name, info->names[i], name_len)) {
+   found = i;
+   break;
+   }

[PATCH i-g-t 1/8] lib: Extract igt_drm_clients from intel_gpu_top

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Extract some code into a new library to prepare for further work towards
making a vendor agnostic gputop tool.

Signed-off-by: Tvrtko Ursulin 
---
 lib/igt_drm_clients.c | 432 ++
 lib/igt_drm_clients.h |  85 +++
 lib/meson.build   |   8 +
 tools/intel_gpu_top.c | 521 +++---
 tools/meson.build |   2 +-
 5 files changed, 606 insertions(+), 442 deletions(-)
 create mode 100644 lib/igt_drm_clients.c
 create mode 100644 lib/igt_drm_clients.h

diff --git a/lib/igt_drm_clients.c b/lib/igt_drm_clients.c
new file mode 100644
index ..45de2d0f1cc5
--- /dev/null
+++ b/lib/igt_drm_clients.c
@@ -0,0 +1,432 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "igt_drm_clients.h"
+#include "igt_drm_fdinfo.h"
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+#endif
+
+/**
+ * igt_drm_clients_init:
+ * @private_data: private data to store in the struct
+ *
+ * Allocate and initialise the clients structure to be used with further API
+ * calls.
+ */
+struct igt_drm_clients *igt_drm_clients_init(void *private_data)
+{
+   struct igt_drm_clients *clients;
+
+   clients = malloc(sizeof(*clients));
+   if (!clients)
+   return NULL;
+
+   memset(clients, 0, sizeof(*clients));
+
+   clients->private_data = private_data;
+
+   return clients;
+}
+
+static struct igt_drm_client *
+igt_drm_clients_find(struct igt_drm_clients *clients,
+enum igt_drm_client_status status,
+unsigned int id)
+{
+   unsigned int start, num;
+   struct igt_drm_client *c;
+
+   start = status == IGT_DRM_CLIENT_FREE ? clients->active_clients : 0; /* 
Free block at the end. */
+   num = clients->num_clients - start;
+
+   for (c = >client[start]; num; c++, num--) {
+   if (status != c->status)
+   continue;
+
+   if (status == IGT_DRM_CLIENT_FREE || c->id == id)
+   return c;
+   }
+
+   return NULL;
+}
+
+static void
+igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name,
+ const struct drm_client_fdinfo *info)
+{
+   unsigned int i;
+
+   /* Update client pid if it changed (fd sharing). */
+   if (c->pid != pid)
+   c->pid = pid;
+
+   /* Update client name if it changed (fd sharing). */
+   if (strcmp(c->name, name)) {
+   char *p;
+
+   strncpy(c->name, name, sizeof(c->name) - 1);
+   strncpy(c->print_name, name, sizeof(c->print_name) - 1);
+
+   p = c->print_name;
+   while (*p) {
+   if (!isprint(*p))
+   *p = '*';
+   p++;
+   }
+   }
+
+   c->last_runtime = 0;
+   c->total_runtime = 0;
+
+   for (i = 0; i < c->clients->num_classes; i++) {
+   assert(i < ARRAY_SIZE(info->busy));
+
+   if (info->busy[i] < c->last[i])
+   continue; /* It will catch up soon. */
+
+   c->total_runtime += info->busy[i];
+   c->val[i] = info->busy[i] - c->last[i];
+   c->last_runtime += c->val[i];
+   c->last[i] = info->busy[i];
+   }
+
+   c->samples++;
+   c->status = IGT_DRM_CLIENT_ALIVE;
+}
+
+static void
+igt_drm_client_add(struct igt_drm_clients *clients,
+  const struct drm_client_fdinfo *info,
+  unsigned int pid, char *name)
+{
+   struct igt_drm_client *c;
+
+   assert(!igt_drm_clients_find(clients, IGT_DRM_CLIENT_ALIVE, info->id));
+
+   c = igt_drm_clients_find(clients, IGT_DRM_CLIENT_FREE, 0);
+   if (!c) {
+   unsigned int idx = clients->num_clients;
+
+   /*
+* Grow the array a bit past the current requirement to avoid
+* constant reallocation when clients are dynamically appearing
+* and disappearing.
+*/
+   clients->num_clients += (clients->num_clients + 2) / 2;
+   clients->client = realloc(clients->client,
+ clients->num_clients * sizeof(*c));
+   assert(clients->client);
+
+   c = >client[idx];
+   memset(c, 0, (clients->num_clients - idx) * sizeof(*c));
+   }
+
+   c->id = info->id;
+   c->clients = clients;
+   c->val = calloc(clients->num_classes, sizeof(c->val));
+   c->last = calloc(clients->num_classes, sizeof(c->last));
+   assert(c->val && c->last);
+
+   igt_drm_client_update(c, pid, name, info);
+}
+
+static
+void igt_drm_client_free(struct igt_drm_client *c, 

[PATCH i-g-t 0/8] Vendor agnostic gputop

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

This is a pile of patches which implements a rudimentary vendor agnostic gputop
tool based of the new DRM spec as documented in
Documentation/gpu/drm-usage-stats.rst.

First part of the series is code refactoring which should be reasonably stable.
I've tested it all while working on it both against intel_gpu_top and gputop.

Last patch is the actual tool itself. It works but it is rather rudimentary
which is hopefully good enough for a start.

Fundamental difference between intel_gpu_top and gputop is that the former is
centered around a single card and only shows processes belonging to it. Gputop
on the other hand has an idea to show all processes with DRM file descriptors
open and sort them into groups per card. It also makes no effort to provide
sorting modes, well any interactivity, or any pretty names for GPUs or engines.

It looks like this:

DRM minor 0
PID   NAMErender   copy   video
3816  kwin_x11 |███▎  ||  ||  ||  |
3523  Xorg |▊ ||  ||  ||  |
 1120449   mpv |  ||  ||▋ ||  |
 1120529  glxgears |▋ ||  ||  ||  |
 1120449   mpv |▍ ||  ||  ||  |
3860   plasmashell |▏ ||  ||  ||  |
4764   krunner |  ||  ||  ||  |
  575206chrome |  ||  ||  ||  |
  833481   firefox |  ||  ||  ||  |
  892924   thunderbird |  ||  ||  ||  |


I did test it as well with two cards and confirmed that too works.

Rob Clark also tested it with a patch which exports the respective data from the
msm driver and confirmed it works fine. Christian König tested it with in
progress patches for amdgpu and that worked as well.

v2:
 * Fixed SPDX headers and added a bunch of code comments/docs throughout.

Tvrtko Ursulin (8):
  lib: Extract igt_drm_clients from intel_gpu_top
  libdrmfdinfo: Allow specifying custom engine map
  libdrmclients: Record client drm minor
  libdrmclient: Support multiple DRM cards
  libdrmfdinfo: Track largest engine index
  libdrmclient/intel_gpu_top: Decouple hardcoded engine assumptions
  libdrmclient: Enforce client status sort order in the library
  gputop: Basic vendor agnostic GPU top tool

 lib/igt_drm_clients.c   | 503 +
 lib/igt_drm_clients.h   |  87 ++
 lib/igt_drm_fdinfo.c|  50 ++-
 lib/igt_drm_fdinfo.h|  16 +-
 lib/meson.build |   8 +
 tests/i915/drm_fdinfo.c |  19 +-
 tools/gputop.c  | 260 +++
 tools/intel_gpu_top.c   | 677 +++-
 tools/meson.build   |   7 +-
 9 files changed, 1113 insertions(+), 514 deletions(-)
 create mode 100644 lib/igt_drm_clients.c
 create mode 100644 lib/igt_drm_clients.h
 create mode 100644 tools/gputop.c

-- 
2.34.1



Re: [PATCH v2.5] drm/msm/dsi: switch to DRM_PANEL_BRIDGE

2022-11-11 Thread Caleb Connolly

Hi,

This patch has caused a regression on 6.1-rc for some devices that use 
DSI panels. The new behaviour results in the DSI controller being 
switched off before the panel unprepare hook is called. As a result, 
panel drivers which call mipi_dsi_dcs_write() or similar in 
unprepare() fail.


I've noticed it specifically on the OnePlus 6 (with upstream Samsung 
s0fef00 panel driver) and the SHIFT6mq with an out of tree driver.


On 12/07/2022 14:22, Dmitry Baryshkov wrote:

Currently the DSI driver has two separate paths: one if the next device
in a chain is a bridge and another one if the panel is connected
directly to the DSI host. Simplify the code path by using panel-bridge
driver (already selected in Kconfig) and dropping support for
handling the panel directly.

Signed-off-by: Dmitry Baryshkov 
---

I'm not sending this as a separate patchset (I'd like to sort out mdp5
first), but more of a preview of changes related to
msm_dsi_manager_ext_bridge_init().

---
  drivers/gpu/drm/msm/dsi/dsi.c |  35 +---
  drivers/gpu/drm/msm/dsi/dsi.h |  16 +-
  drivers/gpu/drm/msm/dsi/dsi_host.c|  25 ---
  drivers/gpu/drm/msm/dsi/dsi_manager.c | 283 +++---
  4 files changed, 36 insertions(+), 323 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 1625328fa430..4edb9167e600 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -6,14 +6,6 @@
  #include "dsi.h"
  #include "dsi_cfg.h"

-struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi)
-{
-   if (!msm_dsi || !msm_dsi_device_connected(msm_dsi))
-   return NULL;
-
-   return msm_dsi->encoder;
-}
-
  bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi)
  {
unsigned long host_flags = msm_dsi_host_get_mode_flags(msm_dsi->host);
@@ -220,7 +212,6 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct 
drm_device *dev,
 struct drm_encoder *encoder)
  {
struct msm_drm_private *priv;
-   struct drm_bridge *ext_bridge;
int ret;

if (WARN_ON(!encoder) || WARN_ON(!msm_dsi) || WARN_ON(!dev))
@@ -254,26 +245,10 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct 
drm_device *dev,
goto fail;
}

-   /*
-* check if the dsi encoder output is connected to a panel or an
-* external bridge. We create a connector only if we're connected to a
-* drm_panel device. When we're connected to an external bridge, we
-* assume that the drm_bridge driver will create the connector itself.
-*/
-   ext_bridge = msm_dsi_host_get_bridge(msm_dsi->host);
-
-   if (ext_bridge)
-   msm_dsi->connector =
-   msm_dsi_manager_ext_bridge_init(msm_dsi->id);
-   else
-   msm_dsi->connector =
-   msm_dsi_manager_connector_init(msm_dsi->id);
-
-   if (IS_ERR(msm_dsi->connector)) {
-   ret = PTR_ERR(msm_dsi->connector);
+   ret = msm_dsi_manager_ext_bridge_init(msm_dsi->id);
+   if (ret) {
DRM_DEV_ERROR(dev->dev,
"failed to create dsi connector: %d\n", ret);
-   msm_dsi->connector = NULL;
goto fail;
}

@@ -287,12 +262,6 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct 
drm_device *dev,
msm_dsi->bridge = NULL;
}

-   /* don't destroy connector if we didn't make it */
-   if (msm_dsi->connector && !msm_dsi->external_bridge)
-   msm_dsi->connector->funcs->destroy(msm_dsi->connector);
-
-   msm_dsi->connector = NULL;
-
return ret;
  }

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 580a1e6358bf..703e4c88d7fb 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -12,7 +12,6 @@
  #include 
  #include 
  #include 
-#include 

  #include "msm_drv.h"
  #include "disp/msm_disp_snapshot.h"
@@ -49,8 +48,6 @@ struct msm_dsi {
struct drm_device *dev;
struct platform_device *pdev;

-   /* connector managed by us when we're connected to a drm_panel */
-   struct drm_connector *connector;
/* internal dsi bridge attached to MDP interface */
struct drm_bridge *bridge;

@@ -58,10 +55,8 @@ struct msm_dsi {
struct msm_dsi_phy *phy;

/*
-* panel/external_bridge connected to dsi bridge output, only one of the
-* two can be valid at a time
+* external_bridge connected to dsi bridge output
 */
-   struct drm_panel *panel;
struct drm_bridge *external_bridge;

struct device *phy_dev;
@@ -76,8 +71,7 @@ struct msm_dsi {
  /* dsi manager */
  struct drm_bridge *msm_dsi_manager_bridge_init(u8 id);
  void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge);
-struct drm_connector *msm_dsi_manager_connector_init(u8 id);
-struct drm_connector 

Re: [Intel-gfx] [PATCH 0/3] Add _PICK_EVEN_RANGES

2022-11-11 Thread Jani Nikula
On Fri, 21 Oct 2022, Lucas De Marchi  wrote:
> On Wed, Oct 12, 2022 at 12:05:31PM -0700, Lucas De Marchi wrote:
>>On Wed, Oct 12, 2022 at 11:51:48AM +0300, Jani Nikula wrote:
>>>On Tue, 11 Oct 2022, Lucas De Marchi  wrote:
Add a new macro, _PICK_EVEN_RANGES, that supports using 2 address
ranges. This should cover most of our needs for _MMIO_PLL3 and such.
To show what is achieved with the new macro, convert some PLL-related
macros to use it instead of _MMIO_PLL3.
>>>
>>>While there's nothing particularly wrong about the solution when looked
>>>at in isolation, I do have pretty strong reservations on the whole.
>>>
>>>We have:
>>>
>>>1) _PICK_EVEN() used in _PIPE() and friends
>>>
>>>2) _PICK() used in _MMIO_PIPE3() and friends
>>>
>>>3) ->pipe_offsets[] etc. adjustment used in _MMIO_PIPE2() and friends
>>>
>>>4) ->ddi_index[] mapping proposed in [1]
>>>
>>>5) _PICK_EVEN_RANGES() proposed here
>>>
>>>Originally we only had the first one, when the hardware was
>>>simpler. Every single addition since then made sense at the time, but if
>>>we add 4 & 5 to the mix, I think it's just too many options.
>>>
>>>I think it's time to take a step back and figure out if there's a more
>>>generic approach that could be used.
>>
>>true... I actually see this as replacing most of the uses of _PICK()
>>and giving and extra benefit of removing the worry we are doing
>>out-of-bounds array access. It also allows to more easily move ranges
>>for new platforms, which is my intention here.
>
> Jani, any feedback here or in the possible things to do below? I'd like
> to get a sketch of whatever solution we think could be the right
> direction during next week.

Considering that I basically stalled this but couldn't provide a
decision on a concrete better path forward either,

Acked-by: Jani Nikula 

on the original approach here. Needs a rebase, but it doesn't block us
from the other ideas later either.

Thanks, and sorry,

Jani.



>
> thanks
> Lucas De Marchi
>
>>
>>So I think that we could have something like this if changing it to
>>something else means a bigger refactor. Talking about a big refactor, I
>>still think my series from a few years back would make sense:
>>
>>drm/i915/display: start description-based ddi initialization
>>(https://lore.kernel.org/all/20191223195850.25997-1-lucas.demar...@intel.com/)
>>
>>I think that got stalled due to initialization in the intel_ddi.c trying
>>too much to group together the if/else ladder. But the overall intention
>>of the patch series I believe is still valid today:
>>
>>  (...) create a table-based initialization approach in
>>  which I keep the useful indexes for each platform: these indexes work
>>  similarly to what we have on the pll part. "enum port" is mostly a
>>  "driver thing" and when all the conversions take place, it would allow
>>  us to stop using the port as indexes to register or register bits. "enum
>>  tc_port", "enum phy", etc are not meaningful numbers from the spec POV
>>  and change with every other platform.
>>
>>+Bala who apparently is going to a similar approach in the ddi_index
>>approach.
>>
>>Other possible approaches hat come to mind (just dumping some thoughts,
>>with no actual code/poc):
>>
>>1) Inside display strut we have:
>>
>>  struct {
>>  u8 version;
>>  union {
>>  struct {
>>  i915_reg_t foo;
>>  i915_reg_t bar;
>>  i915_reg_t bla;
>>  } v1;
>>  struct {
>>  i915_reg_t xyz;
>>  i915_reg_t ijk;
>>  } v2;
>>  }
>>  } regs;
>>
>>instead of vesion it could be the "first platform to use it" like we
>>currently have. Those registers would then be initialized during module
>>bind and then we stop doing these conversions to map a platform to a
>>register offset.  It still needs some per-platform change for the
>>bitfields though.
>>
>>idea would be then to enforce using the right struct inside the union by
>>splitting the code in differen compilation units. One platform can
>>evolve from the other with the same compilation unit as long as it is
>>backward-compatible, i.e. we can add more registers, change offsets,
>>etc. But if the HW interface completely changes, it would need to use a
>>different version.
>>
>>2) Looking around what other teams do. In mesa the registers are actually
>>maintained in a xml. Example: gen12.xml
>>
>>
>>  > type="bool"/>
>>  > end="29" type="bool"/>
>>
>>
>>In code it's used like this:
>>
>>reg.HZDepthTestLEGEOptimizationDisable = true;
>>
>>3) Kind of going in the same direction, but more in the kernel side. Maybe
>>switching to regmap?
>>
>>
>>I think one of the things that block this kind of refactors is having to
>>bring them back to all the previous platforms. Maybe going back only
>>until HAS_DDI() would be 

Re: [PATCH v1 9/9] arm64: dts: qcom: sm8350-hdk: Enable lt9611uxc dsi-hdmi bridge

2022-11-11 Thread Robert Foss
On Sat, 29 Oct 2022 at 00:06, Krzysztof Kozlowski
 wrote:
>
> On 28/10/2022 08:08, Robert Foss wrote:
> > The sm8350-hdk ships with the LT9611 UXC DSI/HDMI bridge chip.
> >
> > In order to toggle the board to enable the HDMI output,
> > switch #7 & #8 on the rightmost multi-switch package have
> > to be toggled to On.
> >
> > Signed-off-by: Robert Foss 
> > ---
> >  arch/arm64/boot/dts/qcom/sm8350-hdk.dts | 106 
> >  1 file changed, 106 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts 
> > b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> > index 6e07feb4b3b2..b38b58f8 100644
> > --- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> > +++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> > @@ -20,6 +20,17 @@ chosen {
> >   stdout-path = "serial0:115200n8";
> >   };
> >
> > + hdmi-out {
>
> Generic node names, so hdmi-connector or just connector.

Ack.

>
> > + compatible = "hdmi-connector";
> > + type = "a";
> > +
> > + port {
> > + hdmi_con: endpoint {
> > + remote-endpoint = <_out>;
> > + };
> > + };
> > + };
> > +
> >   vph_pwr: vph-pwr-regulator {
> >   compatible = "regulator-fixed";
> >   regulator-name = "vph_pwr";
> > @@ -29,6 +40,32 @@ vph_pwr: vph-pwr-regulator {
> >   regulator-always-on;
> >   regulator-boot-on;
> >   };
> > +
> > + lt9611_1v2: lt9611-1v2 {
>
> Node names should be generic.
> https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation

Ack.

>
> > + compatible = "regulator-fixed";
> > + regulator-name = "LT9611_1V2";
> > +
> > + vin-supply = <_pwr>;
> > + regulator-min-microvolt = <120>;
> > + regulator-max-microvolt = <120>;
> > + gpio = < 49 GPIO_ACTIVE_HIGH>;
> > + enable-active-high;
> > + regulator-boot-on;
> > + regulator-always-on;
> > + };
> > +
> > + lt9611_3v3: lt9611-3v3 {
>
> Ditto

Ack.

>
>
> > + compatible = "regulator-fixed";
> > + regulator-name = "LT9611_3V3";
> > +
> > + vin-supply = <_bob>;
> > + gpio = < 47 GPIO_ACTIVE_HIGH>;
> > + regulator-min-microvolt = <330>;
> > + regulator-max-microvolt = <330>;
> > + enable-active-high;
> > + regulator-boot-on;
> > + regulator-always-on;
> > + };
> >  };
> >
> >   {
> > @@ -220,6 +257,15 @@  {
> >   {
> >   status = "okay";
> >   vdda-supply = <_l6b_1p2>;
> > +
> > + ports {
> > + port@1 {
> > + endpoint {
> > + remote-endpoint = <_a>;
> > + data-lanes = <0 1 2 3>;
> > + };
> > + };
> > + };
> >  };
> >
> >  _phy  {
> > @@ -231,6 +277,48 @@ _dma1 {
> >   status = "okay";
> >  };
> >
> > + {
> > + status = "okay";
>
> status is the last property

Ack.

>
> > + clock-frequency = <40>;
> > +
> > + lt9611_codec: hdmi-bridge@2b {
> > + compatible = "lontium,lt9611uxc";
> > + reg = <0x2b>;
> > + status = "okay";
>
> Why status?

It should be removed. Fixing in v2.

>
> > +
> > + interrupts-extended = < 50 IRQ_TYPE_EDGE_FALLING>;
> > + reset-gpios = < 48 GPIO_ACTIVE_HIGH>;
> > +
> > + vdd-supply = <_1v2>;
> > + vcc-supply = <_3v3>;
> > +
> > + pinctrl-names = "default";
> > + pinctrl-0 = <_irq_pin _rst_pin>;
> > +
> > + ports {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + port@0 {
> > + reg = <0>;
> > +
> > + lt9611_a: endpoint {
> > + remote-endpoint = <_out>;
> > + };
> > + };
> > +
> > + port@2 {
> > + reg = <2>;
> > +
> > + lt9611_out: endpoint {
> > + remote-endpoint = <_con>;
> > + };
> > + };
> > +
>
> No need for blank line

Ack

>
> > + };
> > + };
> > +};
> > +
> >   {
> >   status = "okay";
> >  };
> > @@ -248,6 +336,10 @@ _id_0 {
> >   status = "okay";
> >  };
> >
> > +_id_2 {
> > + status = "okay";
> > +};
> > +
> >   {
> >   status = "okay";
> >   firmware-name = "qcom/sm8350/slpi.mbn";
> > @@ -544,4 +636,18 @@ usb_hub_enabled_state: usb-hub-enabled-state {
> >   drive-strength = <2>;
> >   output-low;
> >   };
> > +
> > + lt9611_rst_pin: lt9611-rst-state {
> > +

Re: [PATCH v1 9/9] arm64: dts: qcom: sm8350-hdk: Enable lt9611uxc dsi-hdmi bridge

2022-11-11 Thread Robert Foss
On Fri, 28 Oct 2022 at 15:57, Bjorn Andersson  wrote:
>
> On Fri, Oct 28, 2022 at 02:08:12PM +0200, Robert Foss wrote:
> > The sm8350-hdk ships with the LT9611 UXC DSI/HDMI bridge chip.
> >
> > In order to toggle the board to enable the HDMI output,
> > switch #7 & #8 on the rightmost multi-switch package have
> > to be toggled to On.
> >
> > Signed-off-by: Robert Foss 
> > ---
> >  arch/arm64/boot/dts/qcom/sm8350-hdk.dts | 106 
> >  1 file changed, 106 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts 
> > b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> > index 6e07feb4b3b2..b38b58f8 100644
> > --- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> > +++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> > @@ -20,6 +20,17 @@ chosen {
> >   stdout-path = "serial0:115200n8";
> >   };
> >
> > + hdmi-out {
> > + compatible = "hdmi-connector";
> > + type = "a";
> > +
> > + port {
> > + hdmi_con: endpoint {
> > + remote-endpoint = <_out>;
> > + };
> > + };
> > + };
> > +
> >   vph_pwr: vph-pwr-regulator {
> >   compatible = "regulator-fixed";
> >   regulator-name = "vph_pwr";
> > @@ -29,6 +40,32 @@ vph_pwr: vph-pwr-regulator {
> >   regulator-always-on;
> >   regulator-boot-on;
> >   };
> > +
> > + lt9611_1v2: lt9611-1v2 {
> > + compatible = "regulator-fixed";
> > + regulator-name = "LT9611_1V2";
> > +
> > + vin-supply = <_pwr>;
> > + regulator-min-microvolt = <120>;
> > + regulator-max-microvolt = <120>;
> > + gpio = < 49 GPIO_ACTIVE_HIGH>;
> > + enable-active-high;
> > + regulator-boot-on;
> > + regulator-always-on;
>
> Why is this always-on?

It shouldn't be. Removing this in v2.

>
> > + };
> > +
> > + lt9611_3v3: lt9611-3v3 {
> > + compatible = "regulator-fixed";
> > + regulator-name = "LT9611_3V3";
> > +
> > + vin-supply = <_bob>;
> > + gpio = < 47 GPIO_ACTIVE_HIGH>;
> > + regulator-min-microvolt = <330>;
> > + regulator-max-microvolt = <330>;
> > + enable-active-high;
> > + regulator-boot-on;
> > + regulator-always-on;
> > + };
> >  };
> >
> >   {
> > @@ -220,6 +257,15 @@  {
> >   {
> >   status = "okay";
> >   vdda-supply = <_l6b_1p2>;
> > +
> > + ports {
> > + port@1 {
> > + endpoint {
> > + remote-endpoint = <_a>;
> > + data-lanes = <0 1 2 3>;
> > + };
> > + };
> > + };
> >  };
> >
> >  _phy  {
> > @@ -231,6 +277,48 @@ _dma1 {
> >   status = "okay";
> >  };
> >
> > + {
> > + status = "okay";
>
> Please keep status last. (Yes I see that it goes against the convention
> in this file, so let's update that at some point as well)

Ack.

>
> > + clock-frequency = <40>;
> > +
> > + lt9611_codec: hdmi-bridge@2b {
> > + compatible = "lontium,lt9611uxc";
> > + reg = <0x2b>;
> > + status = "okay";
>
> This is the default, you can omit it.

Ack.

>
> > +
> > + interrupts-extended = < 50 IRQ_TYPE_EDGE_FALLING>;
> > + reset-gpios = < 48 GPIO_ACTIVE_HIGH>;
> > +
> > + vdd-supply = <_1v2>;
> > + vcc-supply = <_3v3>;
> > +
> > + pinctrl-names = "default";
> > + pinctrl-0 = <_irq_pin _rst_pin>;
> > +
> > + ports {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + port@0 {
> > + reg = <0>;
> > +
> > + lt9611_a: endpoint {
> > + remote-endpoint = <_out>;
> > + };
> > + };
> > +
> > + port@2 {
> > + reg = <2>;
> > +
> > + lt9611_out: endpoint {
> > + remote-endpoint = <_con>;
> > + };
> > + };
> > +
> > + };
> > + };
> > +};
> > +
> >   {
> >   status = "okay";
> >  };
> > @@ -248,6 +336,10 @@ _id_0 {
> >   status = "okay";
> >  };
> >
> > +_id_2 {
> > + status = "okay";
> > +};
> > +
> >   {
> >   status = "okay";
> >   firmware-name = "qcom/sm8350/slpi.mbn";
> > @@ -544,4 +636,18 @@ usb_hub_enabled_state: usb-hub-enabled-state {
> >   drive-strength = <2>;
> >   output-low;
> >   };
> > +
> > + lt9611_rst_pin: lt9611-rst-state {
> > + pins = "gpio48";
> > + function = "normal";
> > +
> > + output-high;
> > +  

Re: [PATCH v1 8/9] arm64: dts: qcom: sm8350-hdk: Enable display & dsi nodes

2022-11-11 Thread Robert Foss
On Sat, 29 Oct 2022 at 00:03, Krzysztof Kozlowski
 wrote:
>
> On 28/10/2022 08:08, Robert Foss wrote:
> > Enable the display subsystem and the dsi0 output for
> > the sm8350-hdk board.
> >
> > Signed-off-by: Robert Foss 
> > ---
> >  arch/arm64/boot/dts/qcom/sm8350-hdk.dts | 22 ++
> >  1 file changed, 22 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts 
> > b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> > index e6deb08c6da0..6e07feb4b3b2 100644
> > --- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> > +++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> > @@ -213,10 +213,32 @@  {
> >   firmware-name = "qcom/sm8350/cdsp.mbn";
> >  };
> >
> > + {
> > + status = "okay";
> > +};
> > +
> > + {
> > + status = "okay";
>
> Status is the last property.

Ack.

>
>
> Best regards,
> Krzysztof
>


Re: [PATCH v1 7/9] arm64: dts: qcom: sm8350: Add display system nodes

2022-11-11 Thread Robert Foss
On Sat, 29 Oct 2022 at 00:01, Krzysztof Kozlowski
 wrote:
>
> On 28/10/2022 08:08, Robert Foss wrote:
> > Add mdss, mdss_mdp, dsi0, dsi0_phy nodes. With these
> > nodes the display subsystem is configured to support
> > one DSI output.
> >
> > Signed-off-by: Robert Foss 
> > ---
> >  arch/arm64/boot/dts/qcom/sm8350.dtsi | 196 ++-
> >  1 file changed, 192 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi 
> > b/arch/arm64/boot/dts/qcom/sm8350.dtsi
> > index b6e44cd3b394..eaa3cdee1860 100644
> > --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
> > +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
> > @@ -3,6 +3,7 @@
> >   * Copyright (c) 2020, Linaro Limited
> >   */
> >
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -2535,14 +2536,200 @@ usb_2_dwc3: usb@a80 {
> >   };
> >   };
> >
> > + mdss: mdss@ae0 {
> > + compatible = "qcom,sm8350-mdss";
> > + reg = <0 0x0ae0 0 0x1000>;
> > + reg-names = "mdss";
> > +
> > + interconnects = <_noc MASTER_MDP0 0 _virt 
> > SLAVE_EBI1 0>,
> > + <_noc MASTER_MDP1 0 _virt 
> > SLAVE_EBI1 0>;
> > + interconnect-names = "mdp0-mem", "mdp1-mem";
> > +
> > + power-domains = < MDSS_GDSC>;
> > + resets = < DISP_CC_MDSS_CORE_BCR>;
> > +
> > + clocks = < DISP_CC_MDSS_AHB_CLK>,
> > +  < GCC_DISP_HF_AXI_CLK>,
> > +  < GCC_DISP_SF_AXI_CLK>,
> > +  < DISP_CC_MDSS_MDP_CLK>;
> > + clock-names = "iface", "bus", "nrt_bus", "core";
> > +
> > + interrupts = ;
> > + interrupt-controller;
> > + #interrupt-cells = <1>;
> > +
> > + status = "ok";
>
> No need for this.

Ack, I'll switch to disabled.

>
> > +
> > + #address-cells = <2>;
> > + #size-cells = <2>;
> > + ranges;
> > +
> > + mdss_mdp: mdp@ae01000 {
>
> Node name: display-controller

Ack.

> > + compatible = "qcom,sm8350-dpu";
> > + reg = <0 0x0ae01000 0 0x8f000>,
> > +   <0 0x0aeb 0 0x2008>;
> > + reg-names = "mdp", "vbif";
> > + iommus = <_smmu 0x820 0x402>;
> > +
> > + clocks = < GCC_DISP_HF_AXI_CLK>,
> > + < GCC_DISP_SF_AXI_CLK>,
> > + < DISP_CC_MDSS_AHB_CLK>,
> > + < DISP_CC_MDSS_MDP_LUT_CLK>,
> > + < DISP_CC_MDSS_MDP_CLK>,
> > + < DISP_CC_MDSS_VSYNC_CLK>;
> > + clock-names = "bus",
> > +   "nrt_bus",
> > +   "iface",
> > +   "lut",
> > +   "core",
> > +   "vsync";
> > +
> > + assigned-clocks = < 
> > DISP_CC_MDSS_VSYNC_CLK>;
> > + assigned-clock-rates = <1920>;
> > +
> > + operating-points-v2 = <_opp_table>;
> > + power-domains = < SM8350_MMCX>;
> > +
> > + interrupt-parent = <>;
> > + interrupts = <0>;
> > +
> > + status = "ok";
> > +
> > + ports {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + port@0 {
> > + reg = <0>;
> > + dpu_intf1_out: endpoint {
> > + remote-endpoint = 
> > <_in>;
> > + };
> > + };
> > + };
> > +
> > + mdp_opp_table: mdp-opp-table {
>
> I have doubts that it passes dtbs_checks... opp-table

Ack.

>
> > + compatible = "operating-points-v2";
> > +
> > + opp-2 {
> > + opp-hz = /bits/ 64 
> > <2>;
> > + required-opps = 
> > <_opp_low_svs>;
> > + };
> > +
> > + opp-3 {
> > +  

Re: [PATCH] amdgpu_dm_2027: Add pointer check

2022-11-11 Thread Harry Wentland
The commit title should user the drm/amd/display prefix.
It might also be good to be more specific, like:
drm/amd/display: Check dc_resource_state_construct succeeded

On 11/11/22 02:14, Denis Arefev wrote:
> Return value of a function 'dc_create_state' is
> dereferenced at amdgpu_dm.c:2027 without checking for null
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 

Does this fix a test case? If so, please describe.

> Signed-off-by: Denis Arefev 
> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> 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 0f7749e9424d..529483997154 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -1960,7 +1960,9 @@ static int dm_resume(void *handle)
>   dc_release_state(dm_state->context);
>   dm_state->context = dc_create_state(dm->dc);
>   /* TODO: Remove dc_state->dccg, use dc->dccg directly. */
> - dc_resource_state_construct(dm->dc, dm_state->context);
> + if (dm_state->context) {
> + dc_resource_state_construct(dm->dc, dm_state->context);
> + }

I don't see how this won't leave the driver state in a
mess. Are you sure this isn't a fatal error?

Harry

>  
>   /* Before powering on DC we need to re-initialize DMUB. */
>   r = dm_dmub_hw_init(adev);



[Bug 216625] [regression] GPU lockup on Radeon R7 Kaveri

2022-11-11 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=216625

--- Comment #6 from Alex Deucher (alexdeuc...@gmail.com) ---
(In reply to Pierre Ossman from comment #5)
> 
> Could the issue be with the firmware? Has that changed recently for these
> devices?
> 
> The last good firmware should be:
> 
>   linux-firmware-20220509-132.fc34.noarch
> 
> And the first bad firmware should be:
> 
>   linux-firmware-20220708-136.fc35.noarch

Not likely. The firmware for this chip has not changed in years.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [RESEND PATCH] drm/tegra: switch to using devm_fwnode_gpiod_get()

2022-11-11 Thread Thierry Reding
From: Thierry Reding 

On Mon, 7 Nov 2022 20:41:42 -0800, Dmitry Torokhov wrote:
> devm_gpiod_get_from_of_node() is going away and GPIO consumers should
> use generic device/firmware node APIs to fetch GPIOs assigned to them.
> Switch the driver to use devm_fwnode_gpiod_get() instead.
> 
> 

Applied, thanks!

[1/1] drm/tegra: switch to using devm_fwnode_gpiod_get()
  (no commit info)

Best regards,
-- 
Thierry Reding 


Re: [PATCH 10/26] drm: imx/dcss: Remove #ifdef guards for PM related functions

2022-11-11 Thread Laurentiu Palcu
Hi Paul,

On Mon, Nov 07, 2022 at 05:50:50PM +, Paul Cercueil wrote:
> Use the EXPORT_GPL_DEV_PM_OPS() and pm_ptr() macros to handle the PM
> callbacks.
> 
> These macros allow the PM functions to be automatically dropped by the
> compiler when CONFIG_PM is disabled, without having to use #ifdef
> guards.
> 
> This has the advantage of always compiling these functions in,
> independently of any Kconfig option. Thanks to that, bugs and other
> regressions are subsequently easier to catch.
> 
> Signed-off-by: Paul Cercueil 

Reviewed-by: Laurentiu Palcu 
Tested-by: Laurentiu Palcu 

Thanks,
Laurentiu

> ---
> Cc: Laurentiu Palcu 
> Cc: Lucas Stach 
> Cc: Philipp Zabel 
> Cc: Shawn Guo 
> Cc: Sascha Hauer 
> Cc: Pengutronix Kernel Team 
> Cc: Fabio Estevam 
> Cc: NXP Linux Team 
> Cc: linux-arm-ker...@lists.infradead.org
> ---
>  drivers/gpu/drm/imx/dcss/dcss-dev.c | 17 +
>  drivers/gpu/drm/imx/dcss/dcss-dev.h |  7 +++
>  drivers/gpu/drm/imx/dcss/dcss-drv.c |  8 +---
>  3 files changed, 13 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.c 
> b/drivers/gpu/drm/imx/dcss/dcss-dev.c
> index 3f5750cc2673..66d9233ffb98 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-dev.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.c
> @@ -249,8 +249,7 @@ void dcss_dev_destroy(struct dcss_dev *dcss)
>   kfree(dcss);
>  }
>  
> -#ifdef CONFIG_PM_SLEEP
> -int dcss_dev_suspend(struct device *dev)
> +static int dcss_dev_suspend(struct device *dev)
>  {
>   struct dcss_dev *dcss = dcss_drv_dev_to_dcss(dev);
>   struct drm_device *ddev = dcss_drv_dev_to_drm(dev);
> @@ -273,7 +272,7 @@ int dcss_dev_suspend(struct device *dev)
>   return 0;
>  }
>  
> -int dcss_dev_resume(struct device *dev)
> +static int dcss_dev_resume(struct device *dev)
>  {
>   struct dcss_dev *dcss = dcss_drv_dev_to_dcss(dev);
>   struct drm_device *ddev = dcss_drv_dev_to_drm(dev);
> @@ -296,10 +295,8 @@ int dcss_dev_resume(struct device *dev)
>  
>   return 0;
>  }
> -#endif /* CONFIG_PM_SLEEP */
>  
> -#ifdef CONFIG_PM
> -int dcss_dev_runtime_suspend(struct device *dev)
> +static int dcss_dev_runtime_suspend(struct device *dev)
>  {
>   struct dcss_dev *dcss = dcss_drv_dev_to_dcss(dev);
>   int ret;
> @@ -313,7 +310,7 @@ int dcss_dev_runtime_suspend(struct device *dev)
>   return 0;
>  }
>  
> -int dcss_dev_runtime_resume(struct device *dev)
> +static int dcss_dev_runtime_resume(struct device *dev)
>  {
>   struct dcss_dev *dcss = dcss_drv_dev_to_dcss(dev);
>  
> @@ -325,4 +322,8 @@ int dcss_dev_runtime_resume(struct device *dev)
>  
>   return 0;
>  }
> -#endif /* CONFIG_PM */
> +
> +EXPORT_GPL_DEV_PM_OPS(dcss_dev_pm_ops) = {
> + RUNTIME_PM_OPS(dcss_dev_runtime_suspend, dcss_dev_runtime_resume, NULL)
> + SYSTEM_SLEEP_PM_OPS(dcss_dev_suspend, dcss_dev_resume)
> +};
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.h 
> b/drivers/gpu/drm/imx/dcss/dcss-dev.h
> index 1e582270c6ea..f27b87c09599 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-dev.h
> +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.h
> @@ -9,6 +9,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #define SET  0x04
> @@ -95,13 +96,11 @@ struct dcss_dev *dcss_drv_dev_to_dcss(struct device *dev);
>  struct drm_device *dcss_drv_dev_to_drm(struct device *dev);
>  struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output);
>  void dcss_dev_destroy(struct dcss_dev *dcss);
> -int dcss_dev_runtime_suspend(struct device *dev);
> -int dcss_dev_runtime_resume(struct device *dev);
> -int dcss_dev_suspend(struct device *dev);
> -int dcss_dev_resume(struct device *dev);
>  void dcss_enable_dtg_and_ss(struct dcss_dev *dcss);
>  void dcss_disable_dtg_and_ss(struct dcss_dev *dcss);
>  
> +extern const struct dev_pm_ops dcss_dev_pm_ops;
> +
>  /* BLKCTL */
>  int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base);
>  void dcss_blkctl_cfg(struct dcss_blkctl *blkctl);
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-drv.c 
> b/drivers/gpu/drm/imx/dcss/dcss-drv.c
> index 1c70f70247f6..431510bd811b 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-drv.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-drv.c
> @@ -117,19 +117,13 @@ static const struct of_device_id dcss_of_match[] = {
>  
>  MODULE_DEVICE_TABLE(of, dcss_of_match);
>  
> -static const struct dev_pm_ops dcss_dev_pm = {
> - SET_SYSTEM_SLEEP_PM_OPS(dcss_dev_suspend, dcss_dev_resume)
> - SET_RUNTIME_PM_OPS(dcss_dev_runtime_suspend,
> -dcss_dev_runtime_resume, NULL)
> -};
> -
>  static struct platform_driver dcss_platform_driver = {
>   .probe  = dcss_drv_platform_probe,
>   .remove = dcss_drv_platform_remove,
>   .driver = {
>   .name = "imx-dcss",
>   .of_match_table = dcss_of_match,
> - .pm = _dev_pm,
> + .pm = pm_ptr(_dev_pm_ops),
>   },
>  };
>  
> -- 
> 2.35.1
> 


[v1] drm/msm/disp/dpu1: add color management support for the crtc

2022-11-11 Thread Kalyan Thota
Add color management support for the crtc provided there are
enough dspps that can be allocated from the catalogue.

Changes in v1:
- cache color enabled state in the dpu crtc obj (Dmitry)
- simplify dspp allocation while creating crtc (Dmitry)
- register for color when crtc is created (Dmitry)

Signed-off-by: Kalyan Thota 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c|  5 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  6 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  7 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 53 -
 4 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 4170fbe..ca4c3b3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1571,7 +1571,7 @@ static const struct drm_crtc_helper_funcs 
dpu_crtc_helper_funcs = {
 
 /* initialize crtc */
 struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
-   struct drm_plane *cursor)
+   struct drm_plane *cursor, unsigned long 
features)
 {
struct drm_crtc *crtc = NULL;
struct dpu_crtc *dpu_crtc = NULL;
@@ -1583,6 +1583,7 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, 
struct drm_plane *plane,
 
crtc = _crtc->base;
crtc->dev = dev;
+   dpu_crtc->color_enabled = features & BIT(DPU_DSPP_PCC);
 
spin_lock_init(_crtc->spin_lock);
atomic_set(_crtc->frame_pending, 0);
@@ -1604,7 +1605,7 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, 
struct drm_plane *plane,
 
drm_crtc_helper_add(crtc, _crtc_helper_funcs);
 
-   drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
+   drm_crtc_enable_color_mgmt(crtc, 0, dpu_crtc->color_enabled, 0);
 
/* save user friendly CRTC name for later */
snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 539b68b..342f9ae 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -136,6 +136,7 @@ struct dpu_crtc_frame_event {
  * @enabled   : whether the DPU CRTC is currently enabled. updated in the
  *  commit-thread, not state-swap time which is earlier, so
  *  safe to make decisions on during VBLANK on/off work
+ * @color_enabled : whether crtc supports color management
  * @feature_list  : list of color processing features supported on a crtc
  * @active_list   : list of color processing features are active
  * @dirty_list: list of color processing features are dirty
@@ -164,7 +165,7 @@ struct dpu_crtc {
u64 play_count;
ktime_t vblank_cb_time;
bool enabled;
-
+   bool color_enabled;
struct list_head feature_list;
struct list_head active_list;
struct list_head dirty_list;
@@ -269,10 +270,11 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc);
  * @dev: dpu device
  * @plane: base plane
  * @cursor: cursor plane
+ * @features: color features
  * @Return: new crtc object or error
  */
 struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
-  struct drm_plane *cursor);
+  struct drm_plane *cursor, unsigned long 
features);
 
 /**
  * dpu_crtc_register_custom_event - api for enabling/disabling crtc event
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index c9058aa..d72edb8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -579,6 +579,7 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
 static struct msm_display_topology dpu_encoder_get_topology(
struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms,
+   struct dpu_crtc *dpu_crtc,
struct drm_display_mode *mode)
 {
struct msm_display_topology topology = {0};
@@ -607,7 +608,7 @@ static struct msm_display_topology dpu_encoder_get_topology(
else
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
 
-   if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) {
+   if (dpu_crtc->color_enabled) {
if (dpu_kms->catalog->dspp &&
(dpu_kms->catalog->dspp_count >= topology.num_lm))
topology.num_dspp = topology.num_lm;
@@ -642,6 +643,7 @@ static int dpu_encoder_virt_atomic_check(
struct drm_display_mode *adj_mode;
struct msm_display_topology topology;
struct dpu_global_state *global_state;
+   struct dpu_crtc *dpu_crtc;
int i = 0;
int ret = 0;
 
@@ -652,6 +654,7 @@ static int 

[v1] drm/msm/disp/dpu1: populate disp_info with connector type

2022-11-11 Thread Kalyan Thota
Populate disp_info with connector type. Since DRM encoder type
for few encoders can be similar (like eDP and DP) this information
will be useful to differentiate interfaces.

Changes in v1:
- add connector type in the disp_info (Dmitry)
- add helper functions to know encoder type
- update commit text reflecting the change

Signed-off-by: Kalyan Thota 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 44 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 26 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 ++
 drivers/gpu/drm/msm/dp/dp_display.c |  5 
 drivers/gpu/drm/msm/msm_drv.h   |  7 -
 5 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 9c6817b..c9058aa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -217,6 +217,40 @@ static u32 dither_matrix[DITHER_MATRIX_SZ] = {
15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10
 };
 
+bool dpu_encoder_is_external(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc;
+
+   if (!drm_enc)
+   return false;
+
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+   return (dpu_enc->disp_info.connector_type ==
+   DRM_MODE_CONNECTOR_DisplayPort);
+}
+
+bool dpu_encoder_is_virtual(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc;
+
+   if (!drm_enc)
+   return false;
+
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+   return (dpu_enc->disp_info.connector_type == 
DRM_MODE_CONNECTOR_WRITEBACK);
+}
+
+bool dpu_encoder_is_primary(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc;
+
+   if (!drm_enc)
+   return false;
+
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+   return((dpu_enc->disp_info.connector_type == DRM_MODE_CONNECTOR_DSI) ||
+   (dpu_enc->disp_info.connector_type == DRM_MODE_CONNECTOR_eDP));
+}
 
 bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc)
 {
@@ -2412,7 +2446,7 @@ int dpu_encoder_setup(struct drm_device *dev, struct 
drm_encoder *enc,
struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
struct drm_encoder *drm_enc = NULL;
struct dpu_encoder_virt *dpu_enc = NULL;
-   int ret = 0;
+   int ret = 0, intf_i;
 
dpu_enc = to_dpu_encoder_virt(enc);
 
@@ -2424,13 +2458,17 @@ int dpu_encoder_setup(struct drm_device *dev, struct 
drm_encoder *enc,
timer_setup(_enc->frame_done_timer,
dpu_encoder_frame_done_timeout, 0);
 
+   intf_i = disp_info->h_tile_instance[0];
if (disp_info->intf_type == DRM_MODE_ENCODER_DSI)
timer_setup(_enc->vsync_event_timer,
dpu_encoder_vsync_event_handler,
0);
-   else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
+   else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS) {
dpu_enc->wide_bus_en = msm_dp_wide_bus_available(
-   priv->dp[disp_info->h_tile_instance[0]]);
+   priv->dp[intf_i]);
+   disp_info->connector_type =
+   msm_dp_get_connector_type(priv->dp[intf_i]);
+   }
 
INIT_DELAYED_WORK(_enc->delayed_off_work,
dpu_encoder_off_work);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index 9e7236e..d361c5d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -25,16 +25,18 @@
  * @num_of_h_tiles: Number of horizontal tiles in case of split interface
  * @h_tile_instance:Controller instance used per tile. Number of elements 
is
  *  based on num_of_h_tiles
- * @is_cmd_modeBoolean to indicate if the CMD mode is requested
+ * @is_cmd_mode:Boolean to indicate if the CMD mode is requested
+ * @connector_type: DRM_MODE_CONNECTOR_ type
  * @is_te_using_watchdog_timer:  Boolean to indicate watchdog TE is
- *  used instead of panel TE in cmd mode panels
- * @dsc:   DSC configuration data for DSC-enabled displays
+ *  used instead of panel TE in cmd mode panels
+ * @dsc:DSC configuration data for DSC-enabled displays
  */
 struct msm_display_info {
int intf_type;
uint32_t num_of_h_tiles;
uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY];
bool is_cmd_mode;
+   int connector_type;
bool is_te_using_watchdog_timer;
struct drm_dsc_config *dsc;
 };
@@ -224,4 +226,22 @@ void dpu_encoder_cleanup_wb_job(struct drm_encoder 
*drm_enc,
  */
 bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc);
 
+/**
+* 

[v1] drm/msm/disp/dpu1: pin 1 crtc to 1 encoder

2022-11-11 Thread Kalyan Thota
Pin each crtc with one encoder. This arrangement will
disallow crtc switching between encoders and also will
facilitate to advertise certain features on crtc based
on encoder type.

Changes in v1:
- use drm_for_each_encoder macro while iterating through
  encoder list (Dmitry)

Signed-off-by: Kalyan Thota 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 7a5fabc..0d94eec0d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -798,19 +798,20 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
max_crtc_count = min(max_crtc_count, primary_planes_idx);
 
/* Create one CRTC per encoder */
-   for (i = 0; i < max_crtc_count; i++) {
-   crtc = dpu_crtc_init(dev, primary_planes[i], cursor_planes[i]);
-   if (IS_ERR(crtc)) {
-   ret = PTR_ERR(crtc);
-   return ret;
+   i = 0;
+   drm_for_each_encoder(encoder, dev) {
+   if (i < max_crtc_count) {
+   crtc = dpu_crtc_init(dev, primary_planes[i], 
cursor_planes[i]);
+   if (IS_ERR(crtc)) {
+   ret = PTR_ERR(crtc);
+   return ret;
+   }
+   priv->crtcs[priv->num_crtcs++] = crtc;
+   encoder->possible_crtcs = 1 << drm_crtc_index(crtc);
}
-   priv->crtcs[priv->num_crtcs++] = crtc;
+   i++;
}
 
-   /* All CRTCs are compatible with all encoders */
-   drm_for_each_encoder(encoder, dev)
-   encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
-
return 0;
 }
 
-- 
2.7.4



[v9] drm/msm/disp/dpu1: add support for dspp sub block flush in sc7280

2022-11-11 Thread Kalyan Thota
Flush mechanism for DSPP blocks has changed in sc7280 family, it
allows individual sub blocks to be flushed in coordination with
master flush control.

Representation: master_flush && (PCC_flush | IGC_flush .. etc )

This change adds necessary support for the above design.

Changes in v1:
- Few nits (Doug, Dmitry)
- Restrict sub-block flush programming to dpu_hw_ctl file (Dmitry)

Changes in v2:
- Move the address offset to flush macro (Dmitry)
- Seperate ops for the sub block flush (Dmitry)

Changes in v3:
- Reuse the DPU_DSPP_xx enum instead of a new one (Dmitry)

Changes in v4:
- Use shorter version for unsigned int (Stephen)

Changes in v5:
- Spurious patch please ignore.

Changes in v6:
- Add SOB tag (Doug, Dmitry)

Changes in v7:
- Cache flush mask per dspp (Dmitry)
- Few nits (Marijn)

Changes in v8:
- Few nits (Marijn)

Changes in v9:
- use DSPP enum while accessing flush mask to make it readable (Dmitry)
- Few nits (Dmitry)

Signed-off-by: Kalyan Thota 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  5 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  4 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 64 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h |  5 +-
 5 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 601d687..4170fbe 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -766,7 +766,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
 
/* stage config flush mask */
ctl->ops.update_pending_flush_dspp(ctl,
-   mixer[i].hw_dspp->idx);
+   mixer[i].hw_dspp->idx, DPU_DSPP_PCC);
}
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 27f029f..0eecb2f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -65,7 +65,10 @@
(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
 
 #define CTL_SC7280_MASK \
-   (BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | 
BIT(DPU_CTL_VM_CFG))
+   (BIT(DPU_CTL_ACTIVE_CFG) | \
+BIT(DPU_CTL_FETCH_ACTIVE) | \
+BIT(DPU_CTL_VM_CFG) | \
+BIT(DPU_CTL_DSPP_SUB_BLOCK_FLUSH))
 
 #define MERGE_3D_SM8150_MASK (0)
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 38aa38a..126ee37 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -161,10 +161,12 @@ enum {
  * DSPP sub-blocks
  * @DPU_DSPP_PCC Panel color correction block
  * @DPU_DSPP_GC  Gamma correction block
+ * @DPU_DSPP_IGC Inverse gamma correction block
  */
 enum {
DPU_DSPP_PCC = 0x1,
DPU_DSPP_GC,
+   DPU_DSPP_IGC,
DPU_DSPP_MAX
 };
 
@@ -191,6 +193,7 @@ enum {
  * @DPU_CTL_SPLIT_DISPLAY: CTL supports video mode split display
  * @DPU_CTL_FETCH_ACTIVE:  Active CTL for fetch HW (SSPPs)
  * @DPU_CTL_VM_CFG:CTL config to support multiple VMs
+ * @DPU_CTL_DSPP_BLOCK_FLUSH  CTL config to support dspp sub-block flush
  * @DPU_CTL_MAX
  */
 enum {
@@ -198,6 +201,7 @@ enum {
DPU_CTL_ACTIVE_CFG,
DPU_CTL_FETCH_ACTIVE,
DPU_CTL_VM_CFG,
+   DPU_CTL_DSPP_SUB_BLOCK_FLUSH,
DPU_CTL_MAX
 };
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index a35ecb6..0ee8220 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -28,22 +28,23 @@
 #define   CTL_INTF_ACTIVE   0x0F4
 #define   CTL_MERGE_3D_FLUSH0x100
 #define   CTL_DSC_ACTIVE0x0E8
-#define   CTL_DSC_FLUSH0x104
+#define   CTL_DSC_FLUSH 0x104
 #define   CTL_WB_FLUSH  0x108
 #define   CTL_INTF_FLUSH0x110
 #define   CTL_INTF_MASTER   0x134
 #define   CTL_FETCH_PIPE_ACTIVE 0x0FC
+#define   CTL_DSPP_n_FLUSH(n)   ((0x13C) + ((n) * 4))
 
-#define CTL_MIXER_BORDER_OUTBIT(24)
-#define CTL_FLUSH_MASK_CTL  BIT(17)
+#define   CTL_MIXER_BORDER_OUT  BIT(24)
+#define   CTL_FLUSH_MASK_CTLBIT(17)
 
-#define DPU_REG_RESET_TIMEOUT_US2000
-#define  MERGE_3D_IDX   23
-#define  DSC_IDX22
-#define  INTF_IDX   31
-#define WB_IDX  16
-#define CTL_INVALID_BIT 0x
-#define CTL_DEFAULT_GROUP_ID   0xf
+#define   DPU_REG_RESET_TIMEOUT_US  2000
+#define   MERGE_3D_IDX  23
+#define   DSC_IDX   22
+#define   INTF_IDX  31
+#define   WB_IDX16
+#define   

RE: [PATCH 4/4] drm/msm/disp/dpu1: add color management support for the crtc

2022-11-11 Thread Kalyan Thota


>-Original Message-
>From: Dmitry Baryshkov 
>Sent: Wednesday, November 9, 2022 6:02 PM
>To: Kalyan Thota (QUIC) ; dri-
>de...@lists.freedesktop.org; linux-arm-...@vger.kernel.org;
>freedr...@lists.freedesktop.org; devicet...@vger.kernel.org
>Cc: linux-ker...@vger.kernel.org; robdcl...@chromium.org;
>diand...@chromium.org; swb...@chromium.org; Vinod Polimera (QUIC)
>; Abhinav Kumar (QUIC)
>
>Subject: Re: [PATCH 4/4] drm/msm/disp/dpu1: add color management support
>for the crtc
>
>WARNING: This email originated from outside of Qualcomm. Please be wary of
>any links or attachments, and do not enable macros.
>
>On 09/11/2022 15:16, Kalyan Thota wrote:
>> Add color management support for the crtc provided there are enough
>> dspps that can be allocated from the catalogue
>>
>> Signed-off-by: Kalyan Thota 
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 15 ++--
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  6 
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 +++---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 53
>+
>>   4 files changed, 77 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index 4170fbe..6bd3a64 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -18,9 +18,11 @@
>>   #include 
>>   #include 
>>   #include 
>> +#include 
>>   #include 
>>   #include 
>>   #include 
>> +#include "../../../drm_crtc_internal.h"
>
>If it's internal, it is not supposed to be used by other parties, including 
>the msm
>drm. At least a comment why you are including this file would be helpful.
>
>>
>>   #include "dpu_kms.h"
>>   #include "dpu_hw_lm.h"
>> @@ -553,6 +555,17 @@ static void _dpu_crtc_complete_flip(struct drm_crtc
>*crtc)
>>   spin_unlock_irqrestore(>event_lock, flags);
>>   }
>>
>> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc) {
>> + u32 ctm_id = crtc->dev->mode_config.ctm_property->base.id;
>> + u32 gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id;
>> + u32 degamma_id =
>> +crtc->dev->mode_config.degamma_lut_property->base.id;
>> +
>> + return !!(drm_mode_obj_find_prop_id(>base, ctm_id) ||
>> +drm_mode_obj_find_prop_id(>base, gamma_id) ||
>> +drm_mode_obj_find_prop_id(>base, degamma_id));
>> +}
>> +
>>   enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc)
>>   {
>>   struct drm_encoder *encoder;
>> @@ -1604,8 +1617,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device
>> *dev, struct drm_plane *plane,
>>
>>   drm_crtc_helper_add(crtc, _crtc_helper_funcs);
>>
>> - drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
>> -
>>   /* save user friendly CRTC name for later */
>>   snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u",
>> crtc->base.id);
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
>> index 539b68b..8bac395 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
>> @@ -300,4 +300,10 @@ static inline enum dpu_crtc_client_type
>dpu_crtc_get_client_type(
>>   return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT;
>>   }
>>
>> +/**
>> + * dpu_crtc_has_color_enabled - check if the crtc has color
>> +management enabled
>> + * @crtc: Pointer to drm crtc object
>> + */
>> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc);
>> +
>>   #endif /* _DPU_CRTC_H_ */
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> index 4c56a16..ebc3f25 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> @@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder
>*drm_enc)
>>   static struct msm_display_topology dpu_encoder_get_topology(
>>   struct dpu_encoder_virt *dpu_enc,
>>   struct dpu_kms *dpu_kms,
>> - struct drm_display_mode *mode)
>> + struct drm_display_mode *mode,
>> + struct drm_crtc *crtc)
>>   {
>>   struct msm_display_topology topology = {0};
>>   int i, intf_count = 0;
>> @@ -573,11 +574,9 @@ static struct msm_display_topology
>dpu_encoder_get_topology(
>>   else
>>   topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT)
>> ? 2 : 1;
>>
>> - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) {
>> - if (dpu_kms->catalog->dspp &&
>> - (dpu_kms->catalog->dspp_count >= topology.num_lm))
>> + if (dpu_crtc_has_color_enabled(crtc) &&
>> + (dpu_kms->catalog->dspp_count >= topology.num_lm))
>
>See the comment to the previous patch. It still applies here.
>
This function will only populate the requirements for a given topology based on 
mode. If there are not enough 

Re: [PATCH v1 6/9] arm64: dts: qcom: sm8350: Use 2 interconnect cells

2022-11-11 Thread Robert Foss
On Fri, 28 Oct 2022 at 15:44, Bjorn Andersson  wrote:
>
> On Fri, Oct 28, 2022 at 02:08:09PM +0200, Robert Foss wrote:
> > Use two interconnect cells in order to optionally
> > support a path tag.
> >
> > Signed-off-by: Robert Foss 
> > ---
> >  arch/arm64/boot/dts/qcom/sm8350.dtsi | 20 ++--
> >  1 file changed, 10 insertions(+), 10 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi 
> > b/arch/arm64/boot/dts/qcom/sm8350.dtsi
> > index 606fab087945..b6e44cd3b394 100644
> > --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
> > +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
> > @@ -1543,56 +1543,56 @@ apps_smmu: iommu@1500 {
> >   config_noc: interconnect@150 {
> >   compatible = "qcom,sm8350-config-noc";
> >   reg = <0 0x0150 0 0xa580>;
> > - #interconnect-cells = <1>;
> > + #interconnect-cells = <2>;
>
> You also need amend all the interconnects references with the additional
> tag cell.

Ack

>
> Regards,
> Bjorn
>
> >   qcom,bcm-voters = <_bcm_voter>;
> >   };
> >
> >   mc_virt: interconnect@158 {
> >   compatible = "qcom,sm8350-mc-virt";
> >   reg = <0 0x0158 0 0x1000>;
> > - #interconnect-cells = <1>;
> > + #interconnect-cells = <2>;
> >   qcom,bcm-voters = <_bcm_voter>;
> >   };
> >
> >   system_noc: interconnect@168 {
> >   compatible = "qcom,sm8350-system-noc";
> >   reg = <0 0x0168 0 0x1c200>;
> > - #interconnect-cells = <1>;
> > + #interconnect-cells = <2>;
> >   qcom,bcm-voters = <_bcm_voter>;
> >   };
> >
> >   aggre1_noc: interconnect@16e {
> >   compatible = "qcom,sm8350-aggre1-noc";
> >   reg = <0 0x016e 0 0x1f180>;
> > - #interconnect-cells = <1>;
> > + #interconnect-cells = <2>;
> >   qcom,bcm-voters = <_bcm_voter>;
> >   };
> >
> >   aggre2_noc: interconnect@170 {
> >   compatible = "qcom,sm8350-aggre2-noc";
> >   reg = <0 0x0170 0 0x33000>;
> > - #interconnect-cells = <1>;
> > + #interconnect-cells = <2>;
> >   qcom,bcm-voters = <_bcm_voter>;
> >   };
> >
> >   mmss_noc: interconnect@174 {
> >   compatible = "qcom,sm8350-mmss-noc";
> >   reg = <0 0x0174 0 0x1f080>;
> > - #interconnect-cells = <1>;
> > + #interconnect-cells = <2>;
> >   qcom,bcm-voters = <_bcm_voter>;
> >   };
> >
> >   lpass_ag_noc: interconnect@3c4 {
> >   compatible = "qcom,sm8350-lpass-ag-noc";
> >   reg = <0 0x03c4 0 0xf080>;
> > - #interconnect-cells = <1>;
> > + #interconnect-cells = <2>;
> >   qcom,bcm-voters = <_bcm_voter>;
> >   };
> >
> >   compute_noc: interconnect@a0c{
> >   compatible = "qcom,sm8350-compute-noc";
> >   reg = <0 0x0a0c 0 0xa180>;
> > - #interconnect-cells = <1>;
> > + #interconnect-cells = <2>;
> >   qcom,bcm-voters = <_bcm_voter>;
> >   };
> >
> > @@ -2420,14 +2420,14 @@ usb_2_ssphy: phy@88ebe00 {
> >   dc_noc: interconnect@90c {
> >   compatible = "qcom,sm8350-dc-noc";
> >   reg = <0 0x090c 0 0x4200>;
> > - #interconnect-cells = <1>;
> > + #interconnect-cells = <2>;
> >   qcom,bcm-voters = <_bcm_voter>;
> >   };
> >
> >   gem_noc: interconnect@910 {
> >   compatible = "qcom,sm8350-gem-noc";
> >   reg = <0 0x0910 0 0xb4000>;
> > - #interconnect-cells = <1>;
> > + #interconnect-cells = <2>;
> >   qcom,bcm-voters = <_bcm_voter>;
> >   };
> >
> > --
> > 2.34.1
> >


[PATCH v2 2/2] fbdev: Add support for the nomodeset kernel parameter

2022-11-11 Thread Thomas Zimmermann
Support the kernel's nomodeset parameter for all PCI-based fbdev
drivers that use aperture helpers to remove other, hardware-agnostic
graphics drivers.

The parameter is a simple way of using the firmware-provided scanout
buffer if the hardware's native driver is broken. The same effect
could be achieved with per-driver options, but the importance of the
graphics output for many users makes a single, unified approach
worthwhile.

With nomodeset specified, the fbdev driver module will not load. This
unifies behavior with similar DRM drivers. In DRM helpers, modules
first check the nomodeset parameter before registering the PCI
driver. As fbdev has no such module helpers, we have to modify each
driver individually.

The name 'nomodeset' is slightly misleading, but has been chosen for
historical reasons. Several drivers implemented it before it became a
general option for DRM. So keeping the existing name was preferred over
introducing a new one.

v2:
* print a warning if a driver does not init (Helge)
* wrap video_firmware_drivers_only() in helper

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/staging/sm750fb/Kconfig  |  1 +
 drivers/staging/sm750fb/sm750.c  |  3 ++
 drivers/video/fbdev/Kconfig  | 37 
 drivers/video/fbdev/arkfb.c  |  5 +++
 drivers/video/fbdev/asiliantfb.c |  3 ++
 drivers/video/fbdev/aty/aty128fb.c   |  5 +++
 drivers/video/fbdev/aty/atyfb_base.c |  5 +++
 drivers/video/fbdev/aty/radeon_base.c|  5 +++
 drivers/video/fbdev/carminefb.c  |  3 ++
 drivers/video/fbdev/chipsfb.c|  3 ++
 drivers/video/fbdev/cirrusfb.c   |  5 +++
 drivers/video/fbdev/core/fbmem.c | 15 
 drivers/video/fbdev/cyber2000fb.c|  6 +++-
 drivers/video/fbdev/geode/Kconfig|  3 ++
 drivers/video/fbdev/geode/gx1fb_core.c   |  5 +++
 drivers/video/fbdev/geode/gxfb_core.c|  5 +++
 drivers/video/fbdev/geode/lxfb_core.c|  5 +++
 drivers/video/fbdev/gxt4500.c|  3 ++
 drivers/video/fbdev/hyperv_fb.c  |  4 ++-
 drivers/video/fbdev/i740fb.c |  5 +++
 drivers/video/fbdev/i810/i810_main.c |  6 
 drivers/video/fbdev/imsttfb.c|  5 +++
 drivers/video/fbdev/intelfb/intelfbdrv.c |  3 ++
 drivers/video/fbdev/kyro/fbdev.c |  5 +++
 drivers/video/fbdev/matrox/matroxfb_base.c   |  3 ++
 drivers/video/fbdev/mb862xx/mb862xxfbdrv.c   |  3 ++
 drivers/video/fbdev/neofb.c  |  5 +++
 drivers/video/fbdev/nvidia/nvidia.c  |  5 +++
 drivers/video/fbdev/pm2fb.c  |  5 +++
 drivers/video/fbdev/pm3fb.c  |  5 +++
 drivers/video/fbdev/pvr2fb.c |  5 +++
 drivers/video/fbdev/riva/fbdev.c |  5 +++
 drivers/video/fbdev/s3fb.c   |  5 +++
 drivers/video/fbdev/savage/savagefb_driver.c |  3 ++
 drivers/video/fbdev/sis/sis_main.c   |  5 +++
 drivers/video/fbdev/skeletonfb.c |  5 +++
 drivers/video/fbdev/sm712fb.c|  3 ++
 drivers/video/fbdev/sstfb.c  |  3 ++
 drivers/video/fbdev/sunxvr2500.c |  3 ++
 drivers/video/fbdev/sunxvr500.c  |  3 ++
 drivers/video/fbdev/tdfxfb.c |  5 +++
 drivers/video/fbdev/tgafb.c  |  5 +++
 drivers/video/fbdev/tridentfb.c  |  5 +++
 drivers/video/fbdev/vermilion/vermilion.c|  5 +++
 drivers/video/fbdev/via/via-core.c   |  3 ++
 drivers/video/fbdev/vt8623fb.c   |  5 +++
 include/linux/fb.h   |  9 +
 47 files changed, 246 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/sm750fb/Kconfig b/drivers/staging/sm750fb/Kconfig
index 8c0d8a873d5b0..acb6c08d09dce 100644
--- a/drivers/staging/sm750fb/Kconfig
+++ b/drivers/staging/sm750fb/Kconfig
@@ -6,6 +6,7 @@ config FB_SM750
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+   select VIDEO_NOMODESET
help
  Frame buffer driver for the Silicon Motion SM750 chip
  with 2D accelearion and dual head support.
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 168ae2e9005d7..effc7fcc3703f 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -1168,6 +1168,9 @@ static int __init lynxfb_init(void)
 {
char *option;
 
+   if (fb_modesetting_disabled("sm750fb"))
+   return -ENODEV;
+
 #ifdef MODULE
option = g_option;
 #else
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index a98987aa27846..71019b167f8b0 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -227,6 +227,7 @@ config FB_CIRRUS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select 

[PATCH v2 1/2] drm: Move nomodeset kernel parameter to drivers/video

2022-11-11 Thread Thomas Zimmermann
Move the nomodeset kernel parameter to drivers/video to make it
available to non-DRM drivers. Adapt the interface, but keep the DRM
interface drm_firmware_drivers_only() to avoid churn within DRM. The
function should later be inlined into callers.

The parameter disables any DRM graphics driver that would replace a
driver for firmware-provided scanout buffers. It is an option to easily
fallback to basic graphics output if the hardware's native driver is
broken. Moving it to a more prominent location wil make it available
to fbdev as well.

v2:
* clarify the meaning of the nomodeset parameter (Javier)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 Documentation/admin-guide/kernel-parameters.txt   | 15 +--
 MAINTAINERS   |  2 ++
 drivers/gpu/drm/Kconfig   |  7 +--
 drivers/gpu/drm/Makefile  |  1 -
 drivers/video/Kconfig |  4 
 drivers/video/Makefile|  1 +
 .../drm/drm_nomodeset.c => video/nomodeset.c} | 12 +++-
 include/drm/drm_drv.h |  8 +++-
 include/video/nomodeset.h |  8 
 9 files changed, 39 insertions(+), 19 deletions(-)
 rename drivers/{gpu/drm/drm_nomodeset.c => video/nomodeset.c} (63%)
 create mode 100644 include/video/nomodeset.h

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index a465d5242774a..88561b3ce28a4 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3777,12 +3777,15 @@
shutdown the other cpus.  Instead use the REBOOT_VECTOR
irq.
 
-   nomodeset   Disable kernel modesetting. DRM drivers will not perform
-   display-mode changes or accelerated rendering. Only the
-   system framebuffer will be available for use if this was
-   set-up by the firmware or boot loader.
-
-   Useful as fallback, or for testing and debugging.
+   nomodeset   Disable kernel modesetting. Most systems' firmware
+   sets up a display mode and provides framebuffer memory
+   for output. With nomodeset, DRM and fbdev drivers will
+   not load if they could possibly displace the pre-
+   initialized output. Only the system framebuffer will
+   be available for use. The respective drivers will not
+   perform display-mode changes or accelerated rendering.
+
+   Useful as error fallback, or for testing and debugging.
 
nomoduleDisable module load
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 0f624e3ef6235..84b008f5aacbc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6698,8 +6698,10 @@ F:   drivers/gpu/drm/drm_aperture.c
 F: drivers/gpu/drm/tiny/ofdrm.c
 F: drivers/gpu/drm/tiny/simpledrm.c
 F: drivers/video/aperture.c
+F: drivers/video/nomodeset.c
 F: include/drm/drm_aperture.h
 F: include/linux/aperture.h
+F: include/video/nomodeset.h
 
 DRM DRIVER FOR SIS VIDEO CARDS
 S: Orphan / Obsolete
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f30f99166531f..6b11614aecc5b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -8,7 +8,6 @@
 menuconfig DRM
tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI 
support)"
depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA
-   select DRM_NOMODESET
select DRM_PANEL_ORIENTATION_QUIRKS
select HDMI
select FB_CMDLINE
@@ -19,6 +18,7 @@ menuconfig DRM
 # gallium uses SYS_kcmp for os_same_file_description() to de-duplicate
 # device and dmabuf fd. Let's make sure that is available for our userspace.
select KCMP
+   select VIDEO_NOMODESET
help
  Kernel-level support for the Direct Rendering Infrastructure (DRI)
  introduced in XFree86 4.0. If you say Y here, you need to select
@@ -515,11 +515,6 @@ config DRM_EXPORT_FOR_TESTS
 config DRM_PANEL_ORIENTATION_QUIRKS
tristate
 
-# Separate option because nomodeset parameter is global and expected built-in
-config DRM_NOMODESET
-   bool
-   default n
-
 config DRM_LIB_RANDOM
bool
default n
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index c44a54cadb618..f92cd78927110 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -72,7 +72,6 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \
drm_privacy_screen_x86.o
 obj-$(CONFIG_DRM)  += drm.o
 
-obj-$(CONFIG_DRM_NOMODESET) += drm_nomodeset.o
 obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
 
 #
diff --git a/drivers/video/Kconfig 

[PATCH v2 0/2] video/fbdev: Support 'nomodeset' in PCI drivers

2022-11-11 Thread Thomas Zimmermann
Add support for the kernel's 'nomodeset' parameter to PCI-based
fbdev drivers. The option prevents DRM drivers from loading if they
could possibly displace a hardware-agnostic driver that runs on the
firmware framebuffer. It is a fallback for systems on which the
hardware's native driver does not work correctly.

After the work on the aperture helpers and their integration with
fbdev, it can happen that an fbdev driver replaces a hardware-
agnostic DRM driver. Supporting the nomodeset parameter unifies
the behavior among the graphics drivers and subsystems. An fbdev
driver will not replace any hardware-agnostic driver with nomodeset
given.

v2:
* print warning for disabled drivers (Helge)
* improve nomodeset docs (Javier)
* use fbdev-internal helper

Thomas Zimmermann (2):
  drm: Move nomodeset kernel parameter to drivers/video
  fbdev: Add support for the nomodeset kernel parameter

 .../admin-guide/kernel-parameters.txt | 15 +---
 MAINTAINERS   |  2 +
 drivers/gpu/drm/Kconfig   |  7 +---
 drivers/gpu/drm/Makefile  |  1 -
 drivers/staging/sm750fb/Kconfig   |  1 +
 drivers/staging/sm750fb/sm750.c   |  3 ++
 drivers/video/Kconfig |  4 ++
 drivers/video/Makefile|  1 +
 drivers/video/fbdev/Kconfig   | 37 +++
 drivers/video/fbdev/arkfb.c   |  5 +++
 drivers/video/fbdev/asiliantfb.c  |  3 ++
 drivers/video/fbdev/aty/aty128fb.c|  5 +++
 drivers/video/fbdev/aty/atyfb_base.c  |  5 +++
 drivers/video/fbdev/aty/radeon_base.c |  5 +++
 drivers/video/fbdev/carminefb.c   |  3 ++
 drivers/video/fbdev/chipsfb.c |  3 ++
 drivers/video/fbdev/cirrusfb.c|  5 +++
 drivers/video/fbdev/core/fbmem.c  | 15 
 drivers/video/fbdev/cyber2000fb.c |  6 ++-
 drivers/video/fbdev/geode/Kconfig |  3 ++
 drivers/video/fbdev/geode/gx1fb_core.c|  5 +++
 drivers/video/fbdev/geode/gxfb_core.c |  5 +++
 drivers/video/fbdev/geode/lxfb_core.c |  5 +++
 drivers/video/fbdev/gxt4500.c |  3 ++
 drivers/video/fbdev/hyperv_fb.c   |  4 +-
 drivers/video/fbdev/i740fb.c  |  5 +++
 drivers/video/fbdev/i810/i810_main.c  |  6 +++
 drivers/video/fbdev/imsttfb.c |  5 +++
 drivers/video/fbdev/intelfb/intelfbdrv.c  |  3 ++
 drivers/video/fbdev/kyro/fbdev.c  |  5 +++
 drivers/video/fbdev/matrox/matroxfb_base.c|  3 ++
 drivers/video/fbdev/mb862xx/mb862xxfbdrv.c|  3 ++
 drivers/video/fbdev/neofb.c   |  5 +++
 drivers/video/fbdev/nvidia/nvidia.c   |  5 +++
 drivers/video/fbdev/pm2fb.c   |  5 +++
 drivers/video/fbdev/pm3fb.c   |  5 +++
 drivers/video/fbdev/pvr2fb.c  |  5 +++
 drivers/video/fbdev/riva/fbdev.c  |  5 +++
 drivers/video/fbdev/s3fb.c|  5 +++
 drivers/video/fbdev/savage/savagefb_driver.c  |  3 ++
 drivers/video/fbdev/sis/sis_main.c|  5 +++
 drivers/video/fbdev/skeletonfb.c  |  5 +++
 drivers/video/fbdev/sm712fb.c |  3 ++
 drivers/video/fbdev/sstfb.c   |  3 ++
 drivers/video/fbdev/sunxvr2500.c  |  3 ++
 drivers/video/fbdev/sunxvr500.c   |  3 ++
 drivers/video/fbdev/tdfxfb.c  |  5 +++
 drivers/video/fbdev/tgafb.c   |  5 +++
 drivers/video/fbdev/tridentfb.c   |  5 +++
 drivers/video/fbdev/vermilion/vermilion.c |  5 +++
 drivers/video/fbdev/via/via-core.c|  3 ++
 drivers/video/fbdev/vt8623fb.c|  5 +++
 .../drm/drm_nomodeset.c => video/nomodeset.c} | 12 +++---
 include/drm/drm_drv.h |  8 +++-
 include/linux/fb.h|  9 +
 include/video/nomodeset.h |  8 
 56 files changed, 285 insertions(+), 21 deletions(-)
 rename drivers/{gpu/drm/drm_nomodeset.c => video/nomodeset.c} (63%)
 create mode 100644 include/video/nomodeset.h


base-commit: 3aa97a74d622aa26fe79cf4bd819b6a4fd176e90
prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
prerequisite-patch-id: 3f204510fcbf9530d6540bd8e6128cce598988b6
prerequisite-patch-id: a0b503ec2c15fdf17e3c93ff0357fd3c27a791f6
prerequisite-patch-id: 2a2d490c863c0e2cb1b25052049b2f1c63f7c443
prerequisite-patch-id: bfad12b053cc616edbc07b5ea3e8f5793b647a5a
prerequisite-patch-id: a1abb89fd8c741f37732278ea13f142b497d
prerequisite-patch-id: 63b3e0f79bfe4e3e19f389e21c8e0ee010801075
-- 
2.38.0



Re: [PATCH 2/2] fbdev: Add support for the nomodeset kernel parameter

2022-11-11 Thread Helge Deller

On 11/11/22 12:42, Thomas Zimmermann wrote:

Hi

Am 11.11.22 um 11:49 schrieb Helge Deller:

On 11/11/22 10:49, Javier Martinez Canillas wrote:

On 11/8/22 09:16, Thomas Zimmermann wrote:

Hi


[...]



My proposal would be to add a little helper to fbdev that includes your
suggestions:

    bool fb_modesetting_disabled(const char *drvname)
    {
   fwonly = video_firmware_drivers_only()
   if (fbonly && drvname)
pr_warn("")
   return fbonly;
    }


I'm still wondering why you can't simply merge it with what is printed in
  [1] 
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/drm_nomodeset.c#L18


I don't understand. That message is still there after moving the code
around.


Sure.


It is always printed if the nomodeset parameter is given.


Yes, but wouldn't it be better if it would print the name of the really 
affected DRM driver too?
Currently it even shows up if you don't have any graphic card installed (and 
gave that parameter).


In addition to that, you get a per-driver warning for fbdev, so that it's clear 
which drivers are affected.


and a per-drm-driver message would be nice too (can be added by follow-up 
patches).

Helge



Best regards
Thomas



Other than that, your the proposal is okay, if you adjust your patches to
call this new function "fb_modesetting_disabled()" instead of
calling video_firmware_drivers_only() like this:


+    if (video_firmware_drivers_only())
+    return -ENODEV;


Helge






Re: [RFC 02/13] drm: Track clients by tgid and not tid

2022-11-11 Thread Zack Rusin
On Fri, 2022-11-11 at 10:44 +, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin 
> 
> Thread group id (aka pid from userspace point of view) is a more
> interesting thing to show as an owner of a DRM fd, so track and show that
> instead of the thread id.
> 
> In the next patch we will make the owner updated post file descriptor
> handover, which will also be tgid based to avoid ping-pong when multiple
> threads access the fd.
> 
> Signed-off-by: Tvrtko Ursulin 
> Cc: Zack Rusin 
> Cc: linux-graphics-maintai...@vmware.com
> Cc: Alex Deucher 
> Cc: "Christian König" 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 +-
>  drivers/gpu/drm/drm_debugfs.c   | 4 ++--
>  drivers/gpu/drm/drm_file.c  | 2 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_gem.c | 2 +-
>  4 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> index 8ef31d687ef3..4b940f8bd72b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> @@ -967,7 +967,7 @@ static int amdgpu_debugfs_gem_info_show(struct seq_file 
> *m,
> void *unused)
>  * Therefore, we need to protect this ->comm access using RCU.
>  */
> rcu_read_lock();
> -   task = pid_task(file->pid, PIDTYPE_PID);
> +   task = pid_task(file->pid, PIDTYPE_TGID);
> seq_printf(m, "pid %8d command %s:\n", pid_nr(file->pid),
>    task ? task->comm : "");
> rcu_read_unlock();
> diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
> index ee445f4605ba..42f657772025 100644
> --- a/drivers/gpu/drm/drm_debugfs.c
> +++ b/drivers/gpu/drm/drm_debugfs.c
> @@ -80,7 +80,7 @@ static int drm_clients_info(struct seq_file *m, void *data)
> seq_printf(m,
>    "%20s %5s %3s master a %5s %10s\n",
>    "command",
> -  "pid",
> +  "tgid",
>    "dev",
>    "uid",
>    "magic");
> @@ -94,7 +94,7 @@ static int drm_clients_info(struct seq_file *m, void *data)
> bool is_current_master = drm_is_current_master(priv);
>  
> rcu_read_lock(); /* locks pid_task()->comm */
> -   task = pid_task(priv->pid, PIDTYPE_PID);
> +   task = pid_task(priv->pid, PIDTYPE_TGID);
> uid = task ? __task_cred(task)->euid : GLOBAL_ROOT_UID;
> seq_printf(m, "%20s %5d %3d   %c    %c %5d %10u\n",
>    task ? task->comm : "",
> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
> index ba5041137b29..5cde5014cea1 100644
> --- a/drivers/gpu/drm/drm_file.c
> +++ b/drivers/gpu/drm/drm_file.c
> @@ -156,7 +156,7 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor)
> if (!file)
> return ERR_PTR(-ENOMEM);
>  
> -   file->pid = get_pid(task_pid(current));
> +   file->pid = get_pid(task_tgid(current));
> file->minor = minor;
>  
> /* for compatibility root is always authenticated */
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
> b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
> index ce609e7d758f..f2985337aa53 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
> @@ -260,7 +260,7 @@ static int vmw_debugfs_gem_info_show(struct seq_file *m, 
> void
> *unused)
>  * Therefore, we need to protect this ->comm access using RCU.
>  */
> rcu_read_lock();
> -   task = pid_task(file->pid, PIDTYPE_PID);
> +   task = pid_task(file->pid, PIDTYPE_TGID);
> seq_printf(m, "pid %8d command %s:\n", pid_nr(file->pid),
>    task ? task->comm : "");
> rcu_read_unlock();


Yea, that probably makes a lot more sense. Looks good.

Reviewed-by: Zack Rusin 


Re: [PATCH 1/2] drm: Move nomodeset kernel parameter to drivers/video

2022-11-11 Thread Thomas Zimmermann

Hi

Am 11.11.22 um 10:28 schrieb Javier Martinez Canillas:

Hello Thomas,

On 11/7/22 11:49, Thomas Zimmermann wrote:

[...]



diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index a465d5242774a..70178c5f53956 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3777,7 +3777,7 @@
shutdown the other cpus.  Instead use the REBOOT_VECTOR
irq.
  
-	nomodeset	Disable kernel modesetting. DRM drivers will not perform

+   nomodeset   Disable kernel modesetting. Graphics drivers will not 
perform
display-mode changes or accelerated rendering. Only the
system framebuffer will be available for use if this was
set-up by the firmware or boot loader.


Not really part of your patch but probably we should reword this a little bit.

Because as this is written, it implies that not only DRM drivers with feature
DRIVER_MODESET will not be available but also drivers with DRIVER_RENDER. But
that's not the case, render-only drivers usually just ignore this parameter
(but not all IIRC), so I wonder how we could make this comment more accurate.


I see what you mean, but it's hard to describe in simple words. The 
option is a bit fuzzy. It means that a driver will not replace a 
firmware buffer; even if that means it won't initialize at all. I guess 
we should spell that out.




Also maybe we can mention in the comment fbdev and DRM? Just to make it clear
that this will affect to both subsystems? When I first worked on this, there
were a lot of assumptions in the stack (gdm, mutter, plymouth) that nomodeset
basically meant "no DRM but fbdev".


I can change the text to say 'DRM and fbdev drivers'.

Best regards
Thomas



[...]

  
  int drm_dev_set_unique(struct drm_device *dev, const char *name);
  
-extern bool drm_firmware_drivers_only(void);

+/* TODO: Inline drm_firmware_drivers_only() in all its callers. */


I guess you plan to do that as follow-up patches once this series land? Just
to avoid the churn to require acks for all the drivers to merge this series?

The changes looks good to me.

Reviewed-by: Javier Martinez Canillas 



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v1 1/6] dma-buf: Move dma_buf_mmap_internal() to dynamic locking specification

2022-11-11 Thread Christian König

Am 10.11.22 um 21:13 schrieb Dmitry Osipenko:

All dma-buf functions has been moved to dynamic locking specification
The dma_buf_mmap_internal() was missed out by accident. Take reservation
lock around file mapping operation to adhere the common locking convention.

Reported-by: Daniel Vetter 
Signed-off-by: Dmitry Osipenko 


Reviewed-by: Christian König  for this patch here.

Acked-by: Christian König  for the rest of the 
series.


Regards,
Christian.


---
  drivers/dma-buf/dma-buf.c | 7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 13bfd2d09c56..b809513b03fe 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -129,6 +129,7 @@ static struct file_system_type dma_buf_fs_type = {
  static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct 
*vma)
  {
struct dma_buf *dmabuf;
+   int ret;
  
  	if (!is_dma_buf_file(file))

return -EINVAL;
@@ -144,7 +145,11 @@ static int dma_buf_mmap_internal(struct file *file, struct 
vm_area_struct *vma)
dmabuf->size >> PAGE_SHIFT)
return -EINVAL;
  
-	return dmabuf->ops->mmap(dmabuf, vma);

+   dma_resv_lock(dmabuf->resv, NULL);
+   ret = dmabuf->ops->mmap(dmabuf, vma);
+   dma_resv_unlock(dmabuf->resv);
+
+   return ret;
  }
  
  static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence)




Re: [PATCH v8 01/14] drm: exynos: dsi: Fix MIPI_DSI*_NO_* mode flags

2022-11-11 Thread Jagan Teki
On Fri, Nov 11, 2022 at 5:42 PM Nicolas Boichat  wrote:
>
> On Fri, Nov 11, 2022 at 4:49 PM Jagan Teki  wrote:
> >
> > On Fri, Nov 11, 2022 at 6:19 AM Nicolas Boichat  
> > wrote:
> > >
> > > On Fri, Nov 11, 2022 at 2:40 AM Jagan Teki  
> > > wrote:
> > > >
> > > > HFP/HBP/HSA/EOT_PACKET modes in Exynos DSI host specifies
> > > > 0 = Enable and 1 = Disable.
> > >
> > > Oh I see, that's confusing... IMHO you might want to change the
> > > register macro name... (but if that's what the datasheet uses, it
> > > might not be ideal either). At the _very_ least, I'd add a comment in
> > > the code so the next person doesn't attempt to "fix" it again...
> >
> > 02/14 on the same series doing the name change.
> > https://lore.kernel.org/all/20221110183853.3678209-3-ja...@amarulasolutions.com/
>
> Oh thanks I wasn't cc'ed on that one, makes sense.
>
> You can add my reviewed tag to this one, as my HSE comment doesn't change 
> this.
>
> Reviewed-by: Nicolas Boichat 
>
> But please double check HSE.
>
> >
> > >
> > > BTW, are you sure DSIM_HSE_MODE is correct now?
> >
> > Yes, we have tested in imx8m platforms as well. Sébastien Szymanski
> > initially observed this issue on the imx8m platform.
>
> I'll repeat, are you sure about HSE specifically? You invert the
> polarity for HBP, HFP, and HSA, which makes sense given your patch
> 02/14.
>
> I'm concerned about HSE. Is the bit really a disable bit?
> MIPI_DSI_MODE_VIDEO_HSE is supposed to be an enable flag, so you
> should not do `reg |= DSIM_HSE_DISABLE;`, probably.

HSE typically enables bit logic, unlike other bits which are disabled bits.

HseDisableMod:
In Vsync pulse and Vporch area, MIPI DSI master transfers only Hsync
start packet to MIPI DSI slave at
MIPI DSI spec 1.1r02. This bit transfers Hsync end packet in Vsync
pulse and Vporch area (optional).
0 = Disables transfer
1 = Enables transfer

HfpDisableMode:
Specifies HFP disable mode. If this bit set, DSI master ignores HFP
area in Video mode.
0 = Enables
1 = Disables

I think the naming of 'HseDisableMod' is misleading in the datasheet,
but I have used it as per the spec.

Jagan.


Re: [PATCH v1 3/9] drm/msm/dpu: Add SM8350 to hw catalog

2022-11-11 Thread Robert Foss
On Fri, 28 Oct 2022 at 14:27, Dmitry Baryshkov
 wrote:
>
> On 28/10/2022 15:08, Robert Foss wrote:
> > Add compatibility for SM8350 display subsystem, including
> > required entries in DPU hw catalog.
> > ---
> >   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 217 ++
> >   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   1 +
> >   2 files changed, 218 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > index d0ce7612fee8..bc829d7bdd6e 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > @@ -112,6 +112,15 @@
> >BIT(MDP_INTF3_INTR) | \
> >BIT(MDP_INTF4_INTR))
> >
> > +#define IRQ_SM8350_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
> > +  BIT(MDP_SSPP_TOP0_INTR2) | \
> > +  BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> > +  BIT(MDP_INTF0_7xxx_INTR) | \
> > +  BIT(MDP_INTF1_7xxx_INTR) | \
> > +  BIT(MDP_INTF2_7xxx_INTR) | \
> > +  BIT(MDP_INTF3_7xxx_INTR) | \
> > +  0)
> > +
> >   #define IRQ_SC8180X_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
> > BIT(MDP_SSPP_TOP0_INTR2) | \
> > BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> > @@ -364,6 +373,20 @@ static const struct dpu_caps sm8250_dpu_caps = {
> >   .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> >   };
> >
> > +static const struct dpu_caps sm8350_dpu_caps = {
> > + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
> > + .max_mixer_blendstages = 0xb,
> > + .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
> > + .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
> > + .ubwc_version = DPU_HW_UBWC_VER_40,
> > + .has_src_split = true,
> > + .has_dim_layer = true,
> > + .has_idle_pc = true,
> > + .has_3d_merge = true,
> > + .max_linewidth = 4096,
>
> Is it 4096 or 5120?

4096 is what I'm seeing in the downstream dts, except for the
wb-linewidth-linear property which is 5120.

So I would think 4096 is the correct value, what do you think?

>
> > + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> > +};
> > +
> >   static const struct dpu_caps sc7280_dpu_caps = {
> >   .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
> >   .max_mixer_blendstages = 0x7,
> > @@ -501,6 +524,33 @@ static const struct dpu_mdp_cfg sm8250_mdp[] = {
> >   },
> >   };
> >
> > +static const struct dpu_mdp_cfg sm8350_mdp[] = {
> > + {
> > + .name = "top_0", .id = MDP_TOP,
> > + .base = 0x0, .len = 0x494,
> > + .features = 0,
> > + .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */
> > + .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
> > + .reg_off = 0x2AC, .bit_off = 0},
> > + .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
> > + .reg_off = 0x2B4, .bit_off = 0},
> > + .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
> > + .reg_off = 0x2BC, .bit_off = 0},
> > + .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
> > + .reg_off = 0x2C4, .bit_off = 0},
> > + .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
> > + .reg_off = 0x2AC, .bit_off = 8},
> > + .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
> > + .reg_off = 0x2B4, .bit_off = 8},
> > + .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
> > + .reg_off = 0x2BC, .bit_off = 8},
> > + .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
> > + .reg_off = 0x2C4, .bit_off = 8},
> > + .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
> > + .reg_off = 0x2BC, .bit_off = 20},
> > + },
> > +};
> > +
> >   static const struct dpu_mdp_cfg sc7280_mdp[] = {
> >   {
> >   .name = "top_0", .id = MDP_TOP,
> > @@ -659,6 +709,66 @@ static const struct dpu_ctl_cfg sm8150_ctl[] = {
> >   },
> >   };
> >
> > +static const struct dpu_ctl_cfg sm8350_ctl[] = {
> > + {
> > + .name = "ctl_0", .id = CTL_0,
> > + .base = 0x15000, .len = 0x1e8,
> > + .features = BIT(DPU_CTL_SPLIT_DISPLAY) |
> > + BIT(DPU_CTL_PINGPONG_SPLIT) |
> > + BIT(DPU_CTL_ACTIVE_CFG) |
> > + BIT(DPU_CTL_FETCH_ACTIVE) |
> > + BIT(DPU_CTL_VM_CFG) |
> > + BIT(DPU_CTL_UNIFIED_DSPP_FLUSH),
> > + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
> > + },
> > + {
> > + .name = "ctl_1", .id = CTL_1,
> > + .base = 0x16000, .len = 0x1e8,
> > + .features = BIT(DPU_CTL_SPLIT_DISPLAY) |
> > + BIT(DPU_CTL_ACTIVE_CFG) |
> > + BIT(DPU_CTL_FETCH_ACTIVE) |
> > + BIT(DPU_CTL_VM_CFG) |
> > + BIT(DPU_CTL_UNIFIED_DSPP_FLUSH),
>
> The UNIFIED_DSPP_FLUSH is not merged. Could you please change this to
> BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK (for first two CTLs) and
> just CTL_SC7280_MASK for the rest of 

Re: [PATCH 1/2] drm: Move nomodeset kernel parameter to drivers/video

2022-11-11 Thread Thomas Zimmermann

Hi

Am 11.11.22 um 10:28 schrieb Javier Martinez Canillas:

Hello Thomas,

On 11/7/22 11:49, Thomas Zimmermann wrote:

[...]



diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index a465d5242774a..70178c5f53956 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3777,7 +3777,7 @@
shutdown the other cpus.  Instead use the REBOOT_VECTOR
irq.
  
-	nomodeset	Disable kernel modesetting. DRM drivers will not perform

+   nomodeset   Disable kernel modesetting. Graphics drivers will not 
perform
display-mode changes or accelerated rendering. Only the
system framebuffer will be available for use if this was
set-up by the firmware or boot loader.


Not really part of your patch but probably we should reword this a little bit.

Because as this is written, it implies that not only DRM drivers with feature
DRIVER_MODESET will not be available but also drivers with DRIVER_RENDER. But
that's not the case, render-only drivers usually just ignore this parameter
(but not all IIRC), so I wonder how we could make this comment more accurate.

Also maybe we can mention in the comment fbdev and DRM? Just to make it clear
that this will affect to both subsystems? When I first worked on this, there
were a lot of assumptions in the stack (gdm, mutter, plymouth) that nomodeset
basically meant "no DRM but fbdev".

[...]

  
  int drm_dev_set_unique(struct drm_device *dev, const char *name);
  
-extern bool drm_firmware_drivers_only(void);

+/* TODO: Inline drm_firmware_drivers_only() in all its callers. */


I guess you plan to do that as follow-up patches once this series land? Just
to avoid the churn to require acks for all the drivers to merge this series?


Yes. It has no hurry, but we can do that.

Best regards
Thomas



The changes looks good to me.

Reviewed-by: Javier Martinez Canillas 



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH] udmabuf: add vmap method to udmabuf_ops

2022-11-11 Thread Dmitry Osipenko
On 11/11/22 15:05, Christian König wrote:
> Adding Dmitry as well.
> 
> Am 11.11.22 um 12:45 schrieb Lukasz Wiecaszek:
>> The reason behind that patch is associated with videobuf2 subsystem
>> (or more genrally with v4l2 framework) and user created
>> dma buffers (udmabuf). In some circumstances
>> when dealing with V4L2_MEMORY_DMABUF buffers videobuf2 subsystem
>> wants to use dma_buf_vmap() method on the attached dma buffer.
>> As udmabuf does not have .vmap operation implemented,
>> such dma_buf_vmap() natually fails.
>>
>> videobuf2_common: [cap-3473b2f1] __vb2_queue_alloc: allocated
>> 3 buffers, 1 plane(s) each
>> videobuf2_common: [cap-3473b2f1] __prepare_dmabuf: buffer for
>> plane 0 changed
>> videobuf2_common: [cap-3473b2f1] __prepare_dmabuf: failed to
>> map dmabuf for plane 0
>> videobuf2_common: [cap-3473b2f1] __buf_prepare: buffer
>> preparation failed: -14
>>
>> The patch itself seems to be strighforward.
>> It adds implementation of .vmap method to 'struct dma_buf_ops
>> udmabuf_ops'.
>> .vmap method itself uses vm_map_ram() to map pages linearly
>> into the kernel virtual address space (only if such mapping
>> hasn't been created yet).
> 
> Of hand that sounds sane to me.
> 
> You should probably mention somewhere in a code comment that the cached
> vaddr is protected by the reservation lock being taken. That's not
> necessary obvious to everybody.
> 
> Apart from that looks good to me.

Adding a comment won't hurt.

We have the dma_resv_assert_held() in dma_buf_vmap() that will help
spotting a missing lock at runtime by developers. While the
dmbuf_ops->vmap() shouldn't be ever used directly by importers.

-- 
Best regards,
Dmitry



Re: [PATCH v8 01/14] drm: exynos: dsi: Fix MIPI_DSI*_NO_* mode flags

2022-11-11 Thread Nicolas Boichat
On Fri, Nov 11, 2022 at 4:49 PM Jagan Teki  wrote:
>
> On Fri, Nov 11, 2022 at 6:19 AM Nicolas Boichat  wrote:
> >
> > On Fri, Nov 11, 2022 at 2:40 AM Jagan Teki  
> > wrote:
> > >
> > > HFP/HBP/HSA/EOT_PACKET modes in Exynos DSI host specifies
> > > 0 = Enable and 1 = Disable.
> >
> > Oh I see, that's confusing... IMHO you might want to change the
> > register macro name... (but if that's what the datasheet uses, it
> > might not be ideal either). At the _very_ least, I'd add a comment in
> > the code so the next person doesn't attempt to "fix" it again...
>
> 02/14 on the same series doing the name change.
> https://lore.kernel.org/all/20221110183853.3678209-3-ja...@amarulasolutions.com/

Oh thanks I wasn't cc'ed on that one, makes sense.

You can add my reviewed tag to this one, as my HSE comment doesn't change this.

Reviewed-by: Nicolas Boichat 

But please double check HSE.

>
> >
> > BTW, are you sure DSIM_HSE_MODE is correct now?
>
> Yes, we have tested in imx8m platforms as well. Sébastien Szymanski
> initially observed this issue on the imx8m platform.

I'll repeat, are you sure about HSE specifically? You invert the
polarity for HBP, HFP, and HSA, which makes sense given your patch
02/14.

I'm concerned about HSE. Is the bit really a disable bit?
MIPI_DSI_MODE_VIDEO_HSE is supposed to be an enable flag, so you
should not do `reg |= DSIM_HSE_DISABLE;`, probably.

Thanks,

>
> Jagan.


Re: [PATCH] udmabuf: add vmap method to udmabuf_ops

2022-11-11 Thread Christian König

Adding Dmitry as well.

Am 11.11.22 um 12:45 schrieb Lukasz Wiecaszek:

The reason behind that patch is associated with videobuf2 subsystem
(or more genrally with v4l2 framework) and user created
dma buffers (udmabuf). In some circumstances
when dealing with V4L2_MEMORY_DMABUF buffers videobuf2 subsystem
wants to use dma_buf_vmap() method on the attached dma buffer.
As udmabuf does not have .vmap operation implemented,
such dma_buf_vmap() natually fails.

videobuf2_common: [cap-3473b2f1] __vb2_queue_alloc: allocated 3 
buffers, 1 plane(s) each
videobuf2_common: [cap-3473b2f1] __prepare_dmabuf: buffer for plane 0 
changed
videobuf2_common: [cap-3473b2f1] __prepare_dmabuf: failed to map dmabuf 
for plane 0
videobuf2_common: [cap-3473b2f1] __buf_prepare: buffer preparation 
failed: -14

The patch itself seems to be strighforward.
It adds implementation of .vmap method to 'struct dma_buf_ops udmabuf_ops'.
.vmap method itself uses vm_map_ram() to map pages linearly
into the kernel virtual address space (only if such mapping
hasn't been created yet).


Of hand that sounds sane to me.

You should probably mention somewhere in a code comment that the cached 
vaddr is protected by the reservation lock being taken. That's not 
necessary obvious to everybody.


Apart from that looks good to me.

Regards,
Christian.



Signed-off-by: Lukasz Wiecaszek 
---
  drivers/dma-buf/udmabuf.c | 18 ++
  1 file changed, 18 insertions(+)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 2bcdb935a3ac..8649fcbd05c4 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -12,6 +12,7 @@
  #include 
  #include 
  #include 
+#include 
  
  static int list_limit = 1024;

  module_param(list_limit, int, 0644);
@@ -26,6 +27,7 @@ struct udmabuf {
struct page **pages;
struct sg_table *sg;
struct miscdevice *device;
+   void *vaddr;
  };
  
  static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)

@@ -57,6 +59,21 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
return 0;
  }
  
+static int vmap_udmabuf(struct dma_buf *buf, struct dma_buf_map *map)

+{
+   struct udmabuf *ubuf = buf->priv;
+
+   if (!ubuf->vaddr) {
+   ubuf->vaddr = vm_map_ram(ubuf->pages, ubuf->pagecount, -1);
+   if (!ubuf->vaddr)
+   return -EINVAL;
+   }
+
+   dma_buf_map_set_vaddr(map, ubuf->vaddr);
+
+   return 0;
+}
+
  static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 enum dma_data_direction direction)
  {
@@ -159,6 +176,7 @@ static const struct dma_buf_ops udmabuf_ops = {
.unmap_dma_buf = unmap_udmabuf,
.release   = release_udmabuf,
.mmap  = mmap_udmabuf,
+   .vmap  = vmap_udmabuf,
.begin_cpu_access  = begin_cpu_udmabuf,
.end_cpu_access= end_cpu_udmabuf,
  };




Re: [PATCH] drm/amdgpu: Fix memory leak in amdgpu_cs_pass1

2022-11-11 Thread Christian König

Am 10.11.22 um 15:33 schrieb Dong Chenchen:

When p->gang_size equals 0, amdgpu_cs_pass1() will return directly
without freeing chunk_array, which will cause a memory leak issue,
this patch fixes it.

Fixes: 4624459c84d7 ("drm/amdgpu: add gang submit frontend v6")
Signed-off-by: Dong Chenchen 


Good catch, thanks. Patch is Reviewed-by: Christian König 




---
  drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 1bbd39b3b0fc..0e24d6b80e0b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -287,8 +287,10 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
}
}
  
-	if (!p->gang_size)

-   return -EINVAL;
+   if (!p->gang_size) {
+   ret = -EINVAL;
+   goto free_partial_kdata;
+   }
  
  	for (i = 0; i < p->gang_size; ++i) {

ret = amdgpu_job_alloc(p->adev, num_ibs[i], >jobs[i], vm);




Re: [PATCH v5 5/6] drm/mediatek: add mediatek-drm of vdosys0 support for mt8195

2022-11-11 Thread Matthias Brugger




On 27/09/2022 17:27, Jason-JH.Lin wrote:

Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver.

Signed-off-by: Jason-JH.Lin 
---
  drivers/gpu/drm/mediatek/mtk_disp_rdma.c |  6 +
  drivers/gpu/drm/mediatek/mtk_drm_drv.c   | 28 
  2 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 2cb90466798c..66cdd0bc1311 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -374,6 +374,10 @@ static const struct mtk_disp_rdma_data 
mt8192_rdma_driver_data = {
.fifo_size = 5 * SZ_1K,
  };
  
+static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {

+   .fifo_size = 1920,
+};
+
  static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
{ .compatible = "mediatek,mt2701-disp-rdma",
  .data = _rdma_driver_data},
@@ -383,6 +387,8 @@ static const struct of_device_id 
mtk_disp_rdma_driver_dt_match[] = {
  .data = _rdma_driver_data},
{ .compatible = "mediatek,mt8192-disp-rdma",
  .data = _rdma_driver_data},
+   { .compatible = "mediatek,mt8195-disp-rdma",
+ .data = _rdma_driver_data},
{},
  };
  MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index adc9a4f4085b..9b5a7a7ddde0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -195,6 +195,19 @@ static const enum mtk_ddp_comp_id mt8192_mtk_ddp_ext[] = {
DDP_COMPONENT_DPI0,
  };
  
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {

+   DDP_COMPONENT_OVL0,
+   DDP_COMPONENT_RDMA0,
+   DDP_COMPONENT_COLOR0,
+   DDP_COMPONENT_CCORR,
+   DDP_COMPONENT_AAL0,
+   DDP_COMPONENT_GAMMA,
+   DDP_COMPONENT_DITHER0,
+   DDP_COMPONENT_DSC0,
+   DDP_COMPONENT_MERGE0,
+   DDP_COMPONENT_DP_INTF0,
+};
+
  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
.main_path = mt2701_mtk_ddp_main,
.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -253,6 +266,11 @@ static const struct mtk_mmsys_driver_data 
mt8192_mmsys_driver_data = {
.ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext),
  };
  
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {

+   .main_path = mt8195_mtk_ddp_main,
+   .main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
+};
+
  static int mtk_drm_kms_init(struct drm_device *drm)
  {
struct mtk_drm_private *private = drm->dev_private;
@@ -470,12 +488,16 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
  .data = (void *)MTK_DISP_DITHER },
{ .compatible = "mediatek,mt8183-disp-dither",
  .data = (void *)MTK_DISP_DITHER },
+   { .compatible = "mediatek,mt8195-disp-dsc",
+ .data = (void *)MTK_DISP_DSC },
{ .compatible = "mediatek,mt8167-disp-gamma",
  .data = (void *)MTK_DISP_GAMMA, },
{ .compatible = "mediatek,mt8173-disp-gamma",
  .data = (void *)MTK_DISP_GAMMA, },
{ .compatible = "mediatek,mt8183-disp-gamma",
  .data = (void *)MTK_DISP_GAMMA, },
+   { .compatible = "mediatek,mt8195-disp-merge",
+ .data = (void *)MTK_DISP_MERGE },
{ .compatible = "mediatek,mt2701-disp-mutex",
  .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -490,6 +512,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
  .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt8192-disp-mutex",
  .data = (void *)MTK_DISP_MUTEX },
+   { .compatible = "mediatek,mt8195-disp-mutex",
+ .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt8173-disp-od",
  .data = (void *)MTK_DISP_OD },
{ .compatible = "mediatek,mt2701-disp-ovl",
@@ -524,6 +548,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
  .data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8192-disp-rdma",
  .data = (void *)MTK_DISP_RDMA },
+   { .compatible = "mediatek,mt8195-disp-rdma",
+ .data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8173-disp-ufoe",
  .data = (void *)MTK_DISP_UFOE },
{ .compatible = "mediatek,mt8173-disp-wdma",
@@ -568,6 +594,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
  .data = _mmsys_driver_data},
{ .compatible = "mediatek,mt8192-mmsys",
  .data = _mmsys_driver_data},
+   { .compatible = "mediatek,mt8195-vdosys0",
+ .data = _vdosys0_driver_data},


To make this work with older device tree, we will need to provide the same 
driver data to the old compatible:


+   { .compatible = "mediatek,,mt8195-mmsys",
+ .data = _vdosys0_driver_data},
+   }

Regards,
Matthias


{ }
  };
  

Re: [PATCH 2/2] fbdev: Add support for the nomodeset kernel parameter

2022-11-11 Thread Thomas Zimmermann

Hi

Am 11.11.22 um 11:49 schrieb Helge Deller:

On 11/11/22 10:49, Javier Martinez Canillas wrote:

On 11/8/22 09:16, Thomas Zimmermann wrote:

Hi


[...]



My proposal would be to add a little helper to fbdev that includes your
suggestions:

    bool fb_modesetting_disabled(const char *drvname)
    {
   fwonly = video_firmware_drivers_only()
   if (fbonly && drvname)
pr_warn("")
   return fbonly;
    }


I'm still wondering why you can't simply merge it with what is printed in
  [1] 
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/drm_nomodeset.c#L18


I don't understand. That message is still there after moving the code 
around. It is always printed if the nomodeset parameter is given.


In addition to that, you get a per-driver warning for fbdev, so that 
it's clear which drivers are affected.


Best regards
Thomas



Other than that, your the proposal is okay, if you adjust your patches to
call this new function "fb_modesetting_disabled()" instead of
calling video_firmware_drivers_only() like this:


+    if (video_firmware_drivers_only())
+    return -ENODEV;


Helge


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


[Bug 216673] Recurring amdgpu freeze on kernel 6.0.6 only

2022-11-11 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=216673

--- Comment #7 from Stanislav Modrak (stanislav.mod...@gmail.com) ---
(In reply to Michele Della Guardia from comment #6)
> Update: downloaded kernel 6.0.8, applied patches found here:
> 
> https://gitlab.freedesktop.org/drm/amd/-/issues/2113
> 
> and compiled. That problem seems gone. Hope to find patches applied on next
> kernel release.
> 
> Regards

Thanks! I've also noticed the issue and proposed patches. Waiting for it to be
included in an upcoming release.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[syzbot] inconsistent lock state in trace_hardirqs_on

2022-11-11 Thread syzbot
Hello,

syzbot found the following issue on:

HEAD commit:bbed346d5a96 Merge branch 'for-next/core' into for-kernelci
git tree:   git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git 
for-kernelci
console output: https://syzkaller.appspot.com/x/log.txt?x=14c82f3988
kernel config:  https://syzkaller.appspot.com/x/.config?x=3a4a45d2d827c1e
dashboard link: https://syzkaller.appspot.com/bug?extid=6d6c13e35721fb4393fd
compiler:   Debian clang version 
13.0.1-++20220126092033+75e33f71c2da-1~exp1~20220126212112.63, GNU ld (GNU 
Binutils for Debian) 2.35.2
userspace arch: arm64

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image: 
https://storage.googleapis.com/syzbot-assets/e8e91bc79312/disk-bbed346d.raw.xz
vmlinux: 
https://storage.googleapis.com/syzbot-assets/c1cb3fb3b77e/vmlinux-bbed346d.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+6d6c13e35721fb439...@syzkaller.appspotmail.com


WARNING: inconsistent lock state
6.0.0-rc7-syzkaller-18095-gbbed346d5a96 #0 Not tainted

inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
syz-executor.4/21937 [HC0[0]:SC0[0]:HE0:SE1] takes:
8d6384c8 (sync_timeline_list_lock){?...}-{2:2}, at: spin_lock_irq 
include/linux/spinlock.h:374 [inline]
8d6384c8 (sync_timeline_list_lock){?...}-{2:2}, at: 
sync_info_debugfs_show+0x54/0x2dc drivers/dma-buf/sync_debug.c:147
{IN-HARDIRQ-W} state was registered at:
  lock_acquire+0x100/0x1f8 kernel/locking/lockdep.c:5666
  __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
  _raw_spin_lock_irqsave+0x6c/0xb4 kernel/locking/spinlock.c:162
  sync_timeline_debug_remove+0x24/0x80 drivers/dma-buf/sync_debug.c:31
  sync_timeline_free drivers/dma-buf/sw_sync.c:104 [inline]
  kref_put include/linux/kref.h:65 [inline]
  sync_timeline_put drivers/dma-buf/sw_sync.c:116 [inline]
  timeline_fence_release+0xe0/0x15c drivers/dma-buf/sw_sync.c:144
  dma_fence_release+0x70/0x11c drivers/dma-buf/dma-fence.c:549
  kref_put include/linux/kref.h:65 [inline]
  dma_fence_put include/linux/dma-fence.h:276 [inline]
  dma_fence_array_release+0xac/0x154 drivers/dma-buf/dma-fence-array.c:120
  dma_fence_release+0x70/0x11c drivers/dma-buf/dma-fence.c:549
  kref_put include/linux/kref.h:65 [inline]
  dma_fence_put include/linux/dma-fence.h:276 [inline]
  irq_dma_fence_array_work+0x84/0x11c drivers/dma-buf/dma-fence-array.c:52
  irq_work_single kernel/irq_work.c:211 [inline]
  irq_work_run_list kernel/irq_work.c:242 [inline]
  irq_work_run+0xc4/0x29c kernel/irq_work.c:251
  do_handle_IPI arch/arm64/kernel/smp.c:899 [inline]
  ipi_handler+0x120/0x1a8 arch/arm64/kernel/smp.c:922
  handle_percpu_devid_irq+0xb0/0x1c8 kernel/irq/chip.c:930
  generic_handle_irq_desc include/linux/irqdesc.h:158 [inline]
  handle_irq_desc kernel/irq/irqdesc.c:648 [inline]
  generic_handle_domain_irq+0x4c/0x6c kernel/irq/irqdesc.c:704
  __gic_handle_irq drivers/irqchip/irq-gic-v3.c:695 [inline]
  __gic_handle_irq_from_irqson drivers/irqchip/irq-gic-v3.c:746 [inline]
  gic_handle_irq+0x78/0x1b4 drivers/irqchip/irq-gic-v3.c:790
  call_on_irq_stack+0x2c/0x54 arch/arm64/kernel/entry.S:889
  do_interrupt_handler+0x7c/0xc0 arch/arm64/kernel/entry-common.c:274
  __el1_irq arch/arm64/kernel/entry-common.c:470 [inline]
  el1_interrupt+0x34/0x68 arch/arm64/kernel/entry-common.c:485
  el1h_64_irq_handler+0x18/0x24 arch/arm64/kernel/entry-common.c:490
  el1h_64_irq+0x64/0x68 arch/arm64/kernel/entry.S:577
  arch_local_irq_enable arch/arm64/include/asm/irqflags.h:35 [inline]
  __raw_spin_unlock_irq include/linux/spinlock_api_smp.h:159 [inline]
  _raw_spin_unlock_irq+0x44/0x70 kernel/locking/spinlock.c:202
  spin_unlock_irq include/linux/spinlock.h:399 [inline]
  sw_sync_debugfs_release+0xa8/0x158 drivers/dma-buf/sw_sync.c:321
  __fput+0x198/0x3dc fs/file_table.c:320
  fput+0x20/0x30 fs/file_table.c:353
  task_work_run+0xc4/0x14c kernel/task_work.c:177
  exit_task_work include/linux/task_work.h:38 [inline]
  do_exit+0x26c/0xbe0 kernel/exit.c:795
  __arm64_sys_exit_group+0x0/0x18 kernel/exit.c:925
  __do_sys_exit_group kernel/exit.c:936 [inline]
  __se_sys_exit_group kernel/exit.c:934 [inline]
  __wake_up_parent+0x0/0x40 kernel/exit.c:934
  __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
  invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
  el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
  do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
  el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
  el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
  el0t_64_sync+0x18c/0x190 arch/arm64/kernel/entry.S:581
irq event stamp: 872
hardirqs last  enabled at (871): [] 
mod_objcg_state+0x19c/0x204 mm/memcontrol.c:3158
hardirqs last disabled at (872): [] __raw_spin_lock_irq 
include/linux/spinlock_api_smp.h:117 [inline]
hardirqs last disabled at (872): [] 

Re: [PATCH 2/2] fbdev: Add support for the nomodeset kernel parameter

2022-11-11 Thread Helge Deller

On 11/11/22 10:49, Javier Martinez Canillas wrote:

On 11/8/22 09:16, Thomas Zimmermann wrote:

Hi


[...]



My proposal would be to add a little helper to fbdev that includes your
suggestions:

bool fb_modesetting_disabled(const char *drvname)
{
   fwonly = video_firmware_drivers_only()
   if (fbonly && drvname)
pr_warn("")
   return fbonly;
}


I'm still wondering why you can't simply merge it with what is printed in
 [1] 
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/drm_nomodeset.c#L18

Other than that, your the proposal is okay, if you adjust your patches to
call this new function "fb_modesetting_disabled()" instead of
calling video_firmware_drivers_only() like this:


+if (video_firmware_drivers_only())
+return -ENODEV;


Helge


Re: [PATCH printk v3 33/40] printk, xen: fbfront: create/use safe function for forcing preferred

2022-11-11 Thread Petr Mladek
On Mon 2022-11-07 15:22:31, John Ogness wrote:
> With commit 9e124fe16ff2("xen: Enable console tty by default in domU
> if it's not a dummy") a hack was implemented to make sure that the
> tty console remains the console behind the /dev/console device. The
> main problem with the hack is that, after getting the console pointer
> to the tty console, it is assumed the pointer is still valid after
> releasing the console_sem. This assumption is incorrect and unsafe.
> 
> Make the hack safe by introducing a new function
> console_force_preferred_locked() and perform the full operation
> under the console_list_lock.
> 
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -3457,6 +3458,43 @@ int unregister_console(struct console *console)
>  }
>  EXPORT_SYMBOL(unregister_console);
>  
> +/**
> + * console_force_preferred_locked - force a registered console preferred
> + * @con: The registered console to force preferred.
> + *
> + * Must be called under console_list_lock().
> + */
> +void console_force_preferred_locked(struct console *con)
> +{
> + struct console *cur_pref_con;

One more thing. It would make sense to check that it has
really been called under console_list_lock():

lockdep_assert_console_list_lock_held();

> +
> + if (!console_is_registered_locked(con))
> + return;
> +
> + cur_pref_con = console_first();
> +
> + /* Already preferred? */
> + if (cur_pref_con == con)
> + return;
> +

Best Regards,
Petr


[RFC 07/13] drm/cgroup: Add ability to query drm cgroup GPU time

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Add a driver callback and core helper which allow querying the time spent
on GPUs for processes belonging to a group.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/drm_cgroup.c | 24 
 include/drm/drm_clients.h|  2 ++
 include/drm/drm_drv.h| 28 
 3 files changed, 54 insertions(+)

diff --git a/drivers/gpu/drm/drm_cgroup.c b/drivers/gpu/drm/drm_cgroup.c
index 94e6f39b90c7..06810b4c3ff1 100644
--- a/drivers/gpu/drm/drm_cgroup.c
+++ b/drivers/gpu/drm/drm_cgroup.c
@@ -128,3 +128,27 @@ drm_clients_migrate(struct drm_file *file_priv,
atomic_inc(>num);
list_add_tail_rcu(_priv->clink, >file_list);
 }
+
+u64 drm_pid_get_active_time_us(struct pid *pid)
+{
+   struct drm_pid_clients *clients;
+   u64 total = 0;
+
+   rcu_read_lock();
+   clients = xa_load(_pid_clients, (unsigned long)pid);
+   if (clients) {
+   struct drm_file *fpriv;
+
+   list_for_each_entry_rcu(fpriv, >file_list, clink) {
+   const struct drm_cgroup_ops *cg_ops =
+   fpriv->minor->dev->driver->cg_ops;
+
+   if (cg_ops && cg_ops->active_time_us)
+   total += cg_ops->active_time_us(fpriv);
+   }
+   }
+   rcu_read_unlock();
+
+   return total;
+}
+EXPORT_SYMBOL_GPL(drm_pid_get_active_time_us);
diff --git a/include/drm/drm_clients.h b/include/drm/drm_clients.h
index fbb8cffdf7a9..b9b8009c28a6 100644
--- a/include/drm/drm_clients.h
+++ b/include/drm/drm_clients.h
@@ -41,4 +41,6 @@ drm_clients_migrate(struct drm_file *file_priv,
 }
 #endif
 
+u64 drm_pid_get_active_time_us(struct pid *pid);
+
 #endif
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index f6159acb8856..c09fe9bd517f 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -148,6 +148,24 @@ enum drm_driver_feature {
DRIVER_KMS_LEGACY_CONTEXT   = BIT(31),
 };
 
+/**
+ * struct drm_cgroup_ops
+ *
+ * This structure contains a number of callbacks that drivers can provide if
+ * they are able to support one or more of the functionalities implemented by
+ * the DRM cgroup controller.
+ */
+struct drm_cgroup_ops {
+   /**
+* @active_time_us:
+*
+* Optional callback for reporting the GPU time consumed by this client.
+*
+* Used by the DRM core when queried by the DRM cgroup controller.
+*/
+   u64 (*active_time_us) (struct drm_file *);
+};
+
 /**
  * struct drm_driver - DRM driver structure
  *
@@ -459,6 +477,16 @@ struct drm_driver {
 */
const struct file_operations *fops;
 
+#ifdef CONFIG_CGROUP_DRM
+   /**
+* @cg_ops:
+*
+* Optional pointer to driver callbacks facilitating integration with
+* the DRM cgroup controller.
+*/
+   const struct drm_cgroup_ops *cg_ops;
+#endif
+
 #ifdef CONFIG_DRM_LEGACY
/* Everything below here is for legacy driver, never use! */
/* private: */
-- 
2.34.1



[RFC 06/13] drm/cgroup: Allow safe external access to file_priv

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Entry points from the cgroup subsystem into the drm cgroup controller will
need to walk the file_priv structures associated with registered clients
and since those are not RCU protected lets add a hack for now to make this
safe.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/drm_cgroup.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/drm_cgroup.c b/drivers/gpu/drm/drm_cgroup.c
index 56aa8303974a..94e6f39b90c7 100644
--- a/drivers/gpu/drm/drm_cgroup.c
+++ b/drivers/gpu/drm/drm_cgroup.c
@@ -17,6 +17,13 @@ __del_clients(struct drm_pid_clients *clients,
if (atomic_dec_and_test(>num)) {
xa_erase(_pid_clients, pid);
kfree_rcu(clients, rcu);
+
+   /*
+* FIXME: file_priv is not RCU protected so we add this hack
+* to avoid any races with code which walks clients->file_list
+* and accesses file_priv.
+*/
+   synchronize_rcu();
}
 }
 
-- 
2.34.1



[RFC 12/13] drm/i915: Wire up with drm controller GPU time query

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Implement the drm_cgroup_ops->active_time_us callback.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_driver.c | 10 
 drivers/gpu/drm/i915/i915_drm_client.c | 76 ++
 drivers/gpu/drm/i915/i915_drm_client.h |  2 +
 3 files changed, 78 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_driver.c 
b/drivers/gpu/drm/i915/i915_driver.c
index c3d43f9b1e45..96a7da5258c4 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -1894,6 +1894,12 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_VM_DESTROY, i915_gem_vm_destroy_ioctl, 
DRM_RENDER_ALLOW),
 };
 
+#ifdef CONFIG_CGROUP_DRM
+static const struct drm_cgroup_ops i915_drm_cgroup_ops = {
+   .active_time_us = i915_drm_cgroup_get_active_time_us,
+};
+#endif
+
 /*
  * Interface history:
  *
@@ -1922,6 +1928,10 @@ static const struct drm_driver i915_drm_driver = {
.lastclose = i915_driver_lastclose,
.postclose = i915_driver_postclose,
 
+#ifdef CONFIG_CGROUP_DRM
+   .cg_ops = _drm_cgroup_ops,
+#endif
+
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = i915_gem_prime_import,
diff --git a/drivers/gpu/drm/i915/i915_drm_client.c 
b/drivers/gpu/drm/i915/i915_drm_client.c
index b09d1d386574..c9754cb0277f 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.c
+++ b/drivers/gpu/drm/i915/i915_drm_client.c
@@ -75,7 +75,7 @@ void i915_drm_clients_fini(struct i915_drm_clients *clients)
xa_destroy(>xarray);
 }
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) || defined(CONFIG_CGROUP_DRM)
 static const char * const uabi_class_names[] = {
[I915_ENGINE_CLASS_RENDER] = "render",
[I915_ENGINE_CLASS_COPY] = "copy",
@@ -100,22 +100,78 @@ static u64 busy_add(struct i915_gem_context *ctx, 
unsigned int class)
return total;
 }
 
-static void
-show_client_class(struct seq_file *m,
- struct i915_drm_client *client,
- unsigned int class)
+static u64 get_class_active_ns(struct i915_drm_client *client,
+  unsigned int class,
+  unsigned int *capacity)
 {
-   const struct list_head *list = >ctx_list;
-   u64 total = atomic64_read(>past_runtime[class]);
-   const unsigned int capacity =
-   client->clients->i915->engine_uabi_class_count[class];
struct i915_gem_context *ctx;
+   u64 total;
+
+   *capacity =
+   client->clients->i915->engine_uabi_class_count[class];
+   if (!*capacity)
+   return 0;
+
+   total = atomic64_read(>past_runtime[class]);
 
rcu_read_lock();
-   list_for_each_entry_rcu(ctx, list, client_link)
+   list_for_each_entry_rcu(ctx, >ctx_list, client_link)
total += busy_add(ctx, class);
rcu_read_unlock();
 
+   return total;
+}
+#endif
+
+#ifdef CONFIG_CGROUP_DRM
+static bool supports_stats(struct drm_i915_private *i915)
+{
+   if (GRAPHICS_VER(i915) < 8)
+   return false;
+
+   /* temporary... */
+   if (intel_uc_uses_guc_submission(_gt(i915)->uc))
+   return false;
+
+   return true;
+}
+
+u64 i915_drm_cgroup_get_active_time_us(struct drm_file *file)
+{
+   struct drm_i915_file_private *fpriv = file->driver_priv;
+   struct i915_drm_client *client = fpriv->client;
+   unsigned int i;
+   u64 busy = 0;
+
+   if (!supports_stats(client->clients->i915))
+   return 0;
+
+   for (i = 0; i < ARRAY_SIZE(uabi_class_names); i++) {
+   unsigned int capacity;
+   u64 b;
+
+   b = get_class_active_ns(client, i, );
+   if (capacity) {
+   b = DIV_ROUND_UP_ULL(b, capacity * 1000);
+   busy += b;
+   }
+   }
+
+   return busy;
+}
+#endif
+
+#ifdef CONFIG_PROC_FS
+static void
+show_client_class(struct seq_file *m,
+ struct i915_drm_client *client,
+ unsigned int class)
+{
+   unsigned int capacity;
+   u64 total;
+
+   total = get_class_active_ns(client, class, );
+
if (capacity)
seq_printf(m, "drm-engine-%s:\t%llu ns\n",
   uabi_class_names[class], total);
diff --git a/drivers/gpu/drm/i915/i915_drm_client.h 
b/drivers/gpu/drm/i915/i915_drm_client.h
index 69496af996d9..c8439eaa89be 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.h
+++ b/drivers/gpu/drm/i915/i915_drm_client.h
@@ -65,4 +65,6 @@ void i915_drm_client_fdinfo(struct seq_file *m, struct file 
*f);
 
 void i915_drm_clients_fini(struct i915_drm_clients *clients);
 
+u64 i915_drm_cgroup_get_active_time_us(struct drm_file *file);
+
 #endif /* !__I915_DRM_CLIENT_H__ */
-- 
2.34.1



[RFC 13/13] drm/i915: Implement cgroup controller over budget throttling

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

When notified by the drm core we are over our allotted time budget, i915
instance will check if any of the GPU engines it is reponsible for is
fully saturated. If it is, and the client in question is using that
engine, it will throttle it.

For now throttling is done simplistically by lowering the scheduling
priority while client is throttled.

Signed-off-by: Tvrtko Ursulin 
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 37 +++-
 drivers/gpu/drm/i915/i915_driver.c|  1 +
 drivers/gpu/drm/i915/i915_drm_client.c| 93 +++
 drivers/gpu/drm/i915/i915_drm_client.h| 11 +++
 4 files changed, 141 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 1160723c9d2d..280ed90d5001 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -6,6 +6,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -3015,6 +3016,40 @@ static void retire_requests(struct intel_timeline *tl, 
struct i915_request *end)
break;
 }
 
+#ifdef CONFIG_CGROUP_DRM
+static unsigned int
+__get_class(struct drm_i915_file_private *fpriv, const struct i915_request *rq)
+{
+   unsigned int class;
+
+   class = rq->context->engine->uabi_class;
+
+   if (WARN_ON_ONCE(class >= ARRAY_SIZE(fpriv->client->throttle)))
+   class = 0;
+
+   return class;
+}
+
+static void copy_priority(struct i915_sched_attr *attr,
+ const struct i915_execbuffer *eb,
+ const struct i915_request *rq)
+{
+   struct drm_i915_file_private *file_priv = eb->file->driver_priv;
+
+   *attr = eb->gem_context->sched;
+   if (file_priv->client->throttle[__get_class(file_priv, rq)])
+   attr->priority -=
+   1 + prandom_u32_max(-I915_CONTEXT_MIN_USER_PRIORITY / 2);
+}
+#else
+static void copy_priority(struct i915_sched_attr *attr,
+ const struct i915_execbuffer *eb,
+ const struct i915_request *rq)
+{
+   *attr = eb->gem_context->sched;
+}
+#endif
+
 static int eb_request_add(struct i915_execbuffer *eb, struct i915_request *rq,
  int err, bool last_parallel)
 {
@@ -3031,7 +3066,7 @@ static int eb_request_add(struct i915_execbuffer *eb, 
struct i915_request *rq,
 
/* Check that the context wasn't destroyed before submission */
if (likely(!intel_context_is_closed(eb->context))) {
-   attr = eb->gem_context->sched;
+   copy_priority(, eb, rq);
} else {
/* Serialise with context_close via the add_to_timeline */
i915_request_set_error_once(rq, -ENOENT);
diff --git a/drivers/gpu/drm/i915/i915_driver.c 
b/drivers/gpu/drm/i915/i915_driver.c
index 96a7da5258c4..d6c0501af3f4 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -1897,6 +1897,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
 #ifdef CONFIG_CGROUP_DRM
 static const struct drm_cgroup_ops i915_drm_cgroup_ops = {
.active_time_us = i915_drm_cgroup_get_active_time_us,
+   .signal_budget = i915_drm_cgroup_signal_budget,
 };
 #endif
 
diff --git a/drivers/gpu/drm/i915/i915_drm_client.c 
b/drivers/gpu/drm/i915/i915_drm_client.c
index c9754cb0277f..81144c8e8d05 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.c
+++ b/drivers/gpu/drm/i915/i915_drm_client.c
@@ -4,6 +4,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
@@ -159,6 +160,98 @@ u64 i915_drm_cgroup_get_active_time_us(struct drm_file 
*file)
 
return busy;
 }
+
+int i915_drm_cgroup_signal_budget(struct drm_file *file, u64 usage, u64 budget)
+{
+   struct drm_i915_file_private *fpriv = file->driver_priv;
+   u64 class_usage[I915_LAST_UABI_ENGINE_CLASS + 1];
+   u64 class_last[I915_LAST_UABI_ENGINE_CLASS + 1];
+   struct drm_i915_private *i915 = fpriv->dev_priv;
+   struct i915_drm_client *client = fpriv->client;
+   struct intel_engine_cs *engine;
+   bool over = usage > budget;
+   unsigned int i;
+   ktime_t unused;
+   int ret = 0;
+   u64 t;
+
+   if (!supports_stats(i915))
+   return -EINVAL;
+
+   if (usage == 0 && budget == 0)
+   return 0;
+
+printk("i915_drm_cgroup_signal_budget client-id=%u over=%u (%llu/%llu) <%u>\n",
+   client->id, over, usage, budget, client->over_budget);
+
+   if (over) {
+   client->over_budget++;
+   if (!client->over_budget)
+   client->over_budget = 2;
+   } else {
+   client->over_budget = 0;
+   memset(client->class_last, 0, sizeof(client->class_last));
+   memset(client->throttle, 0, sizeof(client->throttle));
+   return 0;
+   }
+
+   memset(class_usage, 0, 

[RFC 11/13] cgroup/drm: Introduce weight based drm cgroup control

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Similar to CPU scheduling, implement a concept of weight in the drm cgroup
controller.

Uses the same range and default as the CPU controller - CGROUP_WEIGHT_MIN,
CGROUP_WEIGHT_DFL and CGROUP_WEIGHT_MAX.

Later each cgroup is assigned a time budget proportionaly based on the
relative weights of it's siblings. This time budget is in turn split by
the group's children and so on.

Children of the root cgroup will be exempt from split budgets and
therefore compete for the GPU time independently and without weight based
control.

This will be used to implement a soft, or best effort signal from drm
cgroup to drm core notifying about groups which are over their allotted
budget.

No guarantees that the limit can be enforced are provided or implied.

Signed-off-by: Tvrtko Ursulin 
---
 Documentation/admin-guide/cgroup-v2.rst |  37 ++
 drivers/gpu/drm/Kconfig |   1 +
 init/Kconfig|   1 +
 kernel/cgroup/drm.c | 507 +++-
 4 files changed, 545 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/cgroup-v2.rst 
b/Documentation/admin-guide/cgroup-v2.rst
index dc254a3cb956..ab115fb4170e 100644
--- a/Documentation/admin-guide/cgroup-v2.rst
+++ b/Documentation/admin-guide/cgroup-v2.rst
@@ -2398,6 +2398,43 @@ HugeTLB Interface Files
 hugetlb pages of  in this cgroup.  Only active in
 use hugetlb pages are included.  The per-node values are in bytes.
 
+DRM
+---
+
+The DRM controller allows configuring scheduling soft limits.
+
+DRM scheduling soft limits
+~~
+
+Because of the heterogenous hardware and driver DRM capabilities, soft limits
+are implemented as a loose co-operative (bi-directional) interface between the
+controller and DRM core.
+
+The controller configures the GPU time allowed per group and periodically scans
+the belonging tasks to detect the over budget condition, at which point it
+invokes a callback notifying the DRM core of the condition.
+
+DRM core provides an API to query per process GPU utilization and 2nd API to
+receive notification from the cgroup controller when the group enters or exits
+the over budget condition.
+
+Individual DRM drivers which implement the interface are expected to act on 
this
+in the best-effort manner only. There are no guarantees that the soft limits
+will be respected.
+
+DRM scheduling soft limits interface files
+~~
+
+  drm.weight
+   Standard cgroup weight based control [1, 1] used to configure the
+   relative distributing of GPU time between the sibling groups.
+
+  drm.period_us (debugging aid during RFC only)
+   An integer representing the period with which the controller should look
+   at the GPU usage by the group and potentially send the over/under budget
+   signal.
+   Value of zero (defaul) disables the soft limit checking.
+
 Misc
 
 
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f30f99166531..e68a58237882 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -7,6 +7,7 @@
 #
 menuconfig DRM
tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI 
support)"
+   default y if CGROUP_DRM=y
depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA
select DRM_NOMODESET
select DRM_PANEL_ORIENTATION_QUIRKS
diff --git a/init/Kconfig b/init/Kconfig
index 70c08f340961..a39b005b9b8a 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1089,6 +1089,7 @@ config CGROUP_RDMA
 
 config CGROUP_DRM
bool "DRM controller"
+   select DRM
help
  Provides the DRM subsystem controller.
 
diff --git a/kernel/cgroup/drm.c b/kernel/cgroup/drm.c
index e165d8f542cc..c893c3738556 100644
--- a/kernel/cgroup/drm.c
+++ b/kernel/cgroup/drm.c
@@ -8,10 +8,38 @@
 #include 
 #include 
 
+#include 
+
 struct drm_cgroup_state {
struct cgroup_subsys_state css;
+
+   unsigned int weight;
+   unsigned int period_us;
+
+   bool scanning_suspended;
+   unsigned int suspended_period_us;
+
+   struct delayed_work scan_work;
+
+   /*
+* Below fields are owned and updated by the scan worker. Either the
+* worker accesses them, or worker needs to be suspended and synced
+* before they can be touched from the outside.
+*/
+   ktime_t prev_timestamp;
+
+   unsigned int sum_children_weights;
+
+   u64 per_s_budget_ns;
+   u64 prev_active_us;
+   u64 active_us;
+
+   bool over;
+   bool over_budget;
 };
 
+static DEFINE_MUTEX(drmcg_mutex);
+
 static inline struct drm_cgroup_state *
 css_to_drmcs(struct cgroup_subsys_state *css)
 {
@@ -23,20 +51,479 @@ static inline struct drm_cgroup_state 
*get_task_drmcs(struct task_struct *task)
return css_to_drmcs(task_get_css(task, drm_cgrp_id));
 }
 
+static u64 drmcs_get_active_time_us(struct drm_cgroup_state *drmcs)
+{
+   struct 

[RFC 04/13] cgroup: Add the DRM cgroup controller

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Skeleton controller without any functionality.

Signed-off-by: Tvrtko Ursulin 
---
 include/linux/cgroup_drm.h|  9 ++
 include/linux/cgroup_subsys.h |  4 +++
 init/Kconfig  |  7 +
 kernel/cgroup/Makefile|  1 +
 kernel/cgroup/drm.c   | 54 +++
 5 files changed, 75 insertions(+)
 create mode 100644 include/linux/cgroup_drm.h
 create mode 100644 kernel/cgroup/drm.c

diff --git a/include/linux/cgroup_drm.h b/include/linux/cgroup_drm.h
new file mode 100644
index ..bf8abc6b8ebf
--- /dev/null
+++ b/include/linux/cgroup_drm.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef _CGROUP_DRM_H
+#define _CGROUP_DRM_H
+
+#endif /* _CGROUP_DRM_H */
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index 445235487230..49460494a010 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -65,6 +65,10 @@ SUBSYS(rdma)
 SUBSYS(misc)
 #endif
 
+#if IS_ENABLED(CONFIG_CGROUP_DRM)
+SUBSYS(drm)
+#endif
+
 /*
  * The following subsystems are not supported on the default hierarchy.
  */
diff --git a/init/Kconfig b/init/Kconfig
index abf65098f1b6..70c08f340961 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1087,6 +1087,13 @@ config CGROUP_RDMA
  Attaching processes with active RDMA resources to the cgroup
  hierarchy is allowed even if can cross the hierarchy's limit.
 
+config CGROUP_DRM
+   bool "DRM controller"
+   help
+ Provides the DRM subsystem controller.
+
+ ...
+
 config CGROUP_FREEZER
bool "Freezer controller"
help
diff --git a/kernel/cgroup/Makefile b/kernel/cgroup/Makefile
index 12f8457ad1f9..849bd2917477 100644
--- a/kernel/cgroup/Makefile
+++ b/kernel/cgroup/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_CGROUP_PIDS) += pids.o
 obj-$(CONFIG_CGROUP_RDMA) += rdma.o
 obj-$(CONFIG_CPUSETS) += cpuset.o
 obj-$(CONFIG_CGROUP_MISC) += misc.o
+obj-$(CONFIG_CGROUP_DRM) += drm.o
 obj-$(CONFIG_CGROUP_DEBUG) += debug.o
diff --git a/kernel/cgroup/drm.c b/kernel/cgroup/drm.c
new file mode 100644
index ..b88c93661df3
--- /dev/null
+++ b/kernel/cgroup/drm.c
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+struct drm_cgroup_state {
+   struct cgroup_subsys_state css;
+};
+
+static inline struct drm_cgroup_state *
+css_to_drmcs(struct cgroup_subsys_state *css)
+{
+   return container_of(css, struct drm_cgroup_state, css);
+}
+
+static void drmcs_free(struct cgroup_subsys_state *css)
+{
+   kfree(css_to_drmcs(css));
+}
+
+static struct drm_cgroup_state root_drmcs = {
+};
+
+static struct cgroup_subsys_state *
+drmcs_alloc(struct cgroup_subsys_state *parent_css)
+{
+   struct drm_cgroup_state *drmcs;
+
+   if (!parent_css)
+   return _drmcs.css;
+
+   drmcs = kzalloc(sizeof(*drmcs), GFP_KERNEL);
+   if (!drmcs)
+   return ERR_PTR(-ENOMEM);
+
+   return >css;
+}
+
+struct cftype files[] = {
+   { } /* Zero entry terminates. */
+};
+
+struct cgroup_subsys drm_cgrp_subsys = {
+   .css_alloc  = drmcs_alloc,
+   .css_free   = drmcs_free,
+   .early_init = false,
+   .legacy_cftypes = files,
+   .dfl_cftypes= files,
+};
-- 
2.34.1



[RFC 10/13] cgroup/drm: Client exit hook

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

We need the ability for DRM core to inform the cgroup controller when a
client has closed a DRM file descriptor. This will allow us not needing
to keep state relating to GPU time usage by tasks sets in the cgroup
controller itself.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/drm_cgroup.c |  8 
 include/linux/cgroup_drm.h   |  4 
 kernel/cgroup/drm.c  | 13 +
 3 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_cgroup.c b/drivers/gpu/drm/drm_cgroup.c
index d3050c744e3e..31a1bf3c8a43 100644
--- a/drivers/gpu/drm/drm_cgroup.c
+++ b/drivers/gpu/drm/drm_cgroup.c
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 
 static DEFINE_XARRAY(drm_pid_clients);
 
@@ -31,6 +32,7 @@ void drm_clients_close(struct drm_file *file_priv)
 {
struct drm_device *dev = file_priv->minor->dev;
struct drm_pid_clients *clients;
+   struct task_struct *task;
struct pid *pid;
 
lockdep_assert_held(>filelist_mutex);
@@ -43,6 +45,12 @@ void drm_clients_close(struct drm_file *file_priv)
if (WARN_ON_ONCE(!clients))
return;
 
+   task = get_pid_task(pid, PIDTYPE_PID);
+   if (task) {
+   drmcgroup_client_exited(task);
+   put_task_struct(task);
+   }
+
__del_clients(clients, file_priv, (unsigned long)pid);
 }
 
diff --git a/include/linux/cgroup_drm.h b/include/linux/cgroup_drm.h
index bf8abc6b8ebf..2f755b896136 100644
--- a/include/linux/cgroup_drm.h
+++ b/include/linux/cgroup_drm.h
@@ -6,4 +6,8 @@
 #ifndef _CGROUP_DRM_H
 #define _CGROUP_DRM_H
 
+struct task_struct;
+
+void drmcgroup_client_exited(struct task_struct *task);
+
 #endif /* _CGROUP_DRM_H */
diff --git a/kernel/cgroup/drm.c b/kernel/cgroup/drm.c
index b88c93661df3..e165d8f542cc 100644
--- a/kernel/cgroup/drm.c
+++ b/kernel/cgroup/drm.c
@@ -18,11 +18,24 @@ css_to_drmcs(struct cgroup_subsys_state *css)
return container_of(css, struct drm_cgroup_state, css);
 }
 
+static inline struct drm_cgroup_state *get_task_drmcs(struct task_struct *task)
+{
+   return css_to_drmcs(task_get_css(task, drm_cgrp_id));
+}
+
 static void drmcs_free(struct cgroup_subsys_state *css)
 {
kfree(css_to_drmcs(css));
 }
 
+void drmcgroup_client_exited(struct task_struct *task)
+{
+   struct drm_cgroup_state *drmcs = get_task_drmcs(task);
+
+   css_put(>css);
+}
+EXPORT_SYMBOL_GPL(drmcgroup_client_exited);
+
 static struct drm_cgroup_state root_drmcs = {
 };
 
-- 
2.34.1



[RFC 05/13] drm/cgroup: Track clients per owning process

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

To enable propagation of settings from the cgroup drm controller to drm we
need to start tracking which processes own which drm clients.

Implement that by tracking the struct pid pointer of the owning process in
a new XArray, pointing to a structure containing a list of associated
struct drm_file pointers.

Clients are added and removed under the filelist mutex and RCU list
operations are used below it to allow for lockless lookup.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/Makefile |   1 +
 drivers/gpu/drm/drm_cgroup.c | 123 +++
 drivers/gpu/drm/drm_file.c   |  21 --
 include/drm/drm_clients.h|  44 +
 include/drm/drm_file.h   |   4 ++
 5 files changed, 189 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_cgroup.c
 create mode 100644 include/drm/drm_clients.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index c44a54cadb61..4495dda2a720 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -59,6 +59,7 @@ drm-$(CONFIG_DRM_LEGACY) += \
drm_scatter.o \
drm_vm.o
 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
+drm-$(CONFIG_CGROUP_DRM) += drm_cgroup.o
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_PANEL) += drm_panel.o
 drm-$(CONFIG_OF) += drm_of.o
diff --git a/drivers/gpu/drm/drm_cgroup.c b/drivers/gpu/drm/drm_cgroup.c
new file mode 100644
index ..56aa8303974a
--- /dev/null
+++ b/drivers/gpu/drm/drm_cgroup.c
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#include 
+#include 
+
+static DEFINE_XARRAY(drm_pid_clients);
+
+static void
+__del_clients(struct drm_pid_clients *clients,
+ struct drm_file *file_priv,
+ unsigned long pid)
+{
+   list_del_rcu(_priv->clink);
+   if (atomic_dec_and_test(>num)) {
+   xa_erase(_pid_clients, pid);
+   kfree_rcu(clients, rcu);
+   }
+}
+
+void drm_clients_close(struct drm_file *file_priv)
+{
+   struct drm_device *dev = file_priv->minor->dev;
+   struct drm_pid_clients *clients;
+   struct pid *pid;
+
+   lockdep_assert_held(>filelist_mutex);
+
+   pid = rcu_access_pointer(file_priv->pid);
+   clients = xa_load(_pid_clients, (unsigned long)pid);
+   if (WARN_ON_ONCE(!clients))
+   return;
+
+   __del_clients(clients, file_priv, (unsigned long)pid);
+}
+
+static struct drm_pid_clients *__alloc_clients(void)
+{
+   struct drm_pid_clients *clients;
+
+   clients = kmalloc(sizeof(*clients), GFP_KERNEL);
+   if (clients) {
+   atomic_set(>num, 0);
+   INIT_LIST_HEAD(>file_list);
+   init_rcu_head(>rcu);
+   }
+
+   return clients;
+}
+
+int drm_clients_open(struct drm_file *file_priv)
+{
+   struct drm_device *dev = file_priv->minor->dev;
+   struct drm_pid_clients *clients;
+   bool new_client = false;
+   unsigned long pid;
+
+   lockdep_assert_held(>filelist_mutex);
+
+   pid = (unsigned long)rcu_access_pointer(file_priv->pid);
+   clients = xa_load(_pid_clients, pid);
+   if (!clients) {
+   clients = __alloc_clients();
+   if (!clients)
+   return -ENOMEM;
+   new_client = true;
+   }
+   atomic_inc(>num);
+   list_add_tail_rcu(_priv->clink, >file_list);
+   if (new_client) {
+   void *xret;
+
+   xret = xa_store(_pid_clients, pid, clients, GFP_KERNEL);
+   if (xa_err(xret)) {
+   list_del_init(_priv->clink);
+   kfree(clients);
+   return PTR_ERR(clients);
+   }
+   }
+
+   return 0;
+}
+
+void
+drm_clients_migrate(struct drm_file *file_priv,
+   unsigned long old,
+   unsigned long new)
+{
+   struct drm_device *dev = file_priv->minor->dev;
+   struct drm_pid_clients *existing_clients;
+   struct drm_pid_clients *clients;
+
+   lockdep_assert_held(>filelist_mutex);
+
+   existing_clients = xa_load(_pid_clients, new);
+   clients = xa_load(_pid_clients, old);
+
+   if (WARN_ON_ONCE(!clients))
+   return;
+   else if (WARN_ON_ONCE(clients == existing_clients))
+   return;
+
+   __del_clients(clients, file_priv, old);
+
+   if (!existing_clients) {
+   void *xret;
+
+   clients = __alloc_clients();
+   if (WARN_ON(!clients))
+   return;
+
+   xret = xa_store(_pid_clients, new, clients, GFP_KERNEL);
+   if (WARN_ON(xa_err(xret)))
+   return;
+   } else {
+   clients = existing_clients;
+   }
+
+   atomic_inc(>num);
+   list_add_tail_rcu(_priv->clink, >file_list);
+}
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index 

[RFC 01/13] drm: Replace DRM_DEBUG with drm_dbg_core in file and ioctl handling

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Replace the deprecated macro with the per-device one.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/drm_file.c  | 21 +++--
 drivers/gpu/drm/drm_ioc32.c | 13 +++--
 drivers/gpu/drm/drm_ioctl.c | 25 +
 3 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index a8b4d918e9a3..ba5041137b29 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -245,10 +245,10 @@ void drm_file_free(struct drm_file *file)
 
dev = file->minor->dev;
 
-   DRM_DEBUG("comm=\"%s\", pid=%d, dev=0x%lx, open_count=%d\n",
- current->comm, task_pid_nr(current),
- (long)old_encode_dev(file->minor->kdev->devt),
- atomic_read(>open_count));
+   drm_dbg_core(dev, "comm=\"%s\", pid=%d, dev=0x%lx, open_count=%d\n",
+current->comm, task_pid_nr(current),
+(long)old_encode_dev(file->minor->kdev->devt),
+atomic_read(>open_count));
 
 #ifdef CONFIG_DRM_LEGACY
if (drm_core_check_feature(dev, DRIVER_LEGACY) &&
@@ -340,8 +340,8 @@ static int drm_open_helper(struct file *filp, struct 
drm_minor *minor)
dev->switch_power_state != DRM_SWITCH_POWER_DYNAMIC_OFF)
return -EINVAL;
 
-   DRM_DEBUG("comm=\"%s\", pid=%d, minor=%d\n", current->comm,
- task_pid_nr(current), minor->index);
+   drm_dbg_core(dev, "comm=\"%s\", pid=%d, minor=%d\n",
+current->comm, task_pid_nr(current), minor->index);
 
priv = drm_file_alloc(minor);
if (IS_ERR(priv))
@@ -450,11 +450,12 @@ EXPORT_SYMBOL(drm_open);
 
 void drm_lastclose(struct drm_device * dev)
 {
-   DRM_DEBUG("\n");
+   drm_dbg_core(dev, "\n");
 
-   if (dev->driver->lastclose)
+   if (dev->driver->lastclose) {
dev->driver->lastclose(dev);
-   DRM_DEBUG("driver lastclose completed\n");
+   drm_dbg_core(dev, "driver lastclose completed\n");
+   }
 
if (drm_core_check_feature(dev, DRIVER_LEGACY))
drm_legacy_dev_reinit(dev);
@@ -485,7 +486,7 @@ int drm_release(struct inode *inode, struct file *filp)
if (drm_dev_needs_global_mutex(dev))
mutex_lock(_global_mutex);
 
-   DRM_DEBUG("open_count = %d\n", atomic_read(>open_count));
+   drm_dbg_core(dev, "open_count = %d\n", atomic_read(>open_count));
 
drm_close_helper(filp);
 
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index 5d82891c3222..49a743f62b4a 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -972,6 +972,7 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, 
unsigned long arg)
 {
unsigned int nr = DRM_IOCTL_NR(cmd);
struct drm_file *file_priv = filp->private_data;
+   struct drm_device *dev = file_priv->minor->dev;
drm_ioctl_compat_t *fn;
int ret;
 
@@ -986,14 +987,14 @@ long drm_compat_ioctl(struct file *filp, unsigned int 
cmd, unsigned long arg)
if (!fn)
return drm_ioctl(filp, cmd, arg);
 
-   DRM_DEBUG("comm=\"%s\", pid=%d, dev=0x%lx, auth=%d, %s\n",
- current->comm, task_pid_nr(current),
- (long)old_encode_dev(file_priv->minor->kdev->devt),
- file_priv->authenticated,
- drm_compat_ioctls[nr].name);
+   drm_dbg_core(dev, "comm=\"%s\", pid=%d, dev=0x%lx, auth=%d, %s\n",
+current->comm, task_pid_nr(current),
+(long)old_encode_dev(file_priv->minor->kdev->devt),
+file_priv->authenticated,
+drm_compat_ioctls[nr].name);
ret = (*fn)(filp, cmd, arg);
if (ret)
-   DRM_DEBUG("ret = %d\n", ret);
+   drm_dbg_core(dev, "ret = %d\n", ret);
return ret;
 }
 EXPORT_SYMBOL(drm_compat_ioctl);
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index ca2a6e6101dc..7c9d66ee917d 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -440,7 +440,7 @@ static int drm_setversion(struct drm_device *dev, void 
*data, struct drm_file *f
 int drm_noop(struct drm_device *dev, void *data,
 struct drm_file *file_priv)
 {
-   DRM_DEBUG("\n");
+   drm_dbg_core(dev, "\n");
return 0;
 }
 EXPORT_SYMBOL(drm_noop);
@@ -856,16 +856,16 @@ long drm_ioctl(struct file *filp,
out_size = 0;
ksize = max(max(in_size, out_size), drv_size);
 
-   DRM_DEBUG("comm=\"%s\" pid=%d, dev=0x%lx, auth=%d, %s\n",
- current->comm, task_pid_nr(current),
- (long)old_encode_dev(file_priv->minor->kdev->devt),
- file_priv->authenticated, ioctl->name);
+   drm_dbg_core(dev, "comm=\"%s\" pid=%d, dev=0x%lx, auth=%d, %s\n",
+current->comm, 

[RFC 09/13] drm/cgroup: Only track clients which are providing drm_cgroup_ops

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

To reduce the number of tracking going on, especially with drivers which
will not support any sort of control from the drm cgroup controller side,
lets express the funcionality as opt-in and use the presence of
drm_cgroup_ops as activation criteria.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/drm_cgroup.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/drm_cgroup.c b/drivers/gpu/drm/drm_cgroup.c
index e3854741c584..d3050c744e3e 100644
--- a/drivers/gpu/drm/drm_cgroup.c
+++ b/drivers/gpu/drm/drm_cgroup.c
@@ -35,6 +35,9 @@ void drm_clients_close(struct drm_file *file_priv)
 
lockdep_assert_held(>filelist_mutex);
 
+   if (!dev->driver->cg_ops)
+   return;
+
pid = rcu_access_pointer(file_priv->pid);
clients = xa_load(_pid_clients, (unsigned long)pid);
if (WARN_ON_ONCE(!clients))
@@ -66,6 +69,9 @@ int drm_clients_open(struct drm_file *file_priv)
 
lockdep_assert_held(>filelist_mutex);
 
+   if (!dev->driver->cg_ops)
+   return 0;
+
pid = (unsigned long)rcu_access_pointer(file_priv->pid);
clients = xa_load(_pid_clients, pid);
if (!clients) {
@@ -101,6 +107,9 @@ drm_clients_migrate(struct drm_file *file_priv,
 
lockdep_assert_held(>filelist_mutex);
 
+   if (!dev->driver->cg_ops)
+   return;
+
existing_clients = xa_load(_pid_clients, new);
clients = xa_load(_pid_clients, old);
 
-- 
2.34.1



[RFC 08/13] drm/cgroup: Add over budget signalling callback

2022-11-11 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Add a new callback via which the drm cgroup controller is notifying the
drm core that a certain process is above its allotted GPU time.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/drm_cgroup.c | 21 +
 include/drm/drm_clients.h|  1 +
 include/drm/drm_drv.h|  8 
 3 files changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/drm_cgroup.c b/drivers/gpu/drm/drm_cgroup.c
index 06810b4c3ff1..e3854741c584 100644
--- a/drivers/gpu/drm/drm_cgroup.c
+++ b/drivers/gpu/drm/drm_cgroup.c
@@ -152,3 +152,24 @@ u64 drm_pid_get_active_time_us(struct pid *pid)
return total;
 }
 EXPORT_SYMBOL_GPL(drm_pid_get_active_time_us);
+
+void drm_pid_signal_budget(struct pid *pid, u64 usage, u64 budget)
+{
+   struct drm_pid_clients *clients;
+
+   rcu_read_lock();
+   clients = xa_load(_pid_clients, (unsigned long)pid);
+   if (clients) {
+   struct drm_file *fpriv;
+
+   list_for_each_entry_rcu(fpriv, >file_list, clink) {
+   const struct drm_cgroup_ops *cg_ops =
+   fpriv->minor->dev->driver->cg_ops;
+
+   if (cg_ops && cg_ops->signal_budget)
+   cg_ops->signal_budget(fpriv, usage, budget);
+   }
+   }
+   rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(drm_pid_signal_budget);
diff --git a/include/drm/drm_clients.h b/include/drm/drm_clients.h
index b9b8009c28a6..356ee92792a6 100644
--- a/include/drm/drm_clients.h
+++ b/include/drm/drm_clients.h
@@ -42,5 +42,6 @@ drm_clients_migrate(struct drm_file *file_priv,
 #endif
 
 u64 drm_pid_get_active_time_us(struct pid *pid);
+void drm_pid_signal_budget(struct pid *pid, u64 usage, u64 budget);
 
 #endif
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index c09fe9bd517f..c30afe97f922 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -164,6 +164,14 @@ struct drm_cgroup_ops {
 * Used by the DRM core when queried by the DRM cgroup controller.
 */
u64 (*active_time_us) (struct drm_file *);
+
+   /**
+* @signal_budget:
+*
+* Optional callback used by the DRM core to forward over/under GPU time
+* messages sent by the DRM cgroup controller.
+*/
+   int (*signal_budget) (struct drm_file *, u64 used, u64 budget);
 };
 
 /**
-- 
2.34.1



  1   2   >