Re: [PATCH 09/10] drm/tidss: IRQ code cleanup

2023-11-02 Thread Tomi Valkeinen

On 01/11/2023 16:52, Laurent Pinchart wrote:

Hi Tomi,

Thank you for the patch.

On Wed, Nov 01, 2023 at 11:17:46AM +0200, Tomi Valkeinen wrote:

The IRQ setup code is overly complex. All we really need to do is
initialize the related fields in struct tidss_device, and request the
IRQ.

We can drop all the HW accesses, as they are pointless: the driver will
set the IRQs correctly when it needs any of the IRQs, and at probe time
we have done a reset, so we know that all the IRQs are masked by default
in the hardware.


Even for K2G ?


Good point. I'll add a simple manual reset for k2g, masking the IRQs and 
disabling the VPs.


 Tomi



Re: [PATCH 08/10] drm/tidss: Add dispc_is_idle()

2023-11-02 Thread Tomi Valkeinen

On 01/11/2023 16:32, Laurent Pinchart wrote:

Hi Tomi,

Thank you for the patch.

On Wed, Nov 01, 2023 at 11:17:45AM +0200, Tomi Valkeinen wrote:

Add a helper function, dispc_is_idle(), which returns whether the DSS is
idle (i.e. is any video port enabled).

For now we add a call to it in the suspend and resume callbacks, and
print a warning if in either place the DSS is not idle.


Could you please explain here why these checks are needed/useful ? Why
would the dispc not be idle ?


I'll drop this. This was mostly a debugging aid for myself when testing 
runtime PM.


 Tomi



Re: [PATCH v4 09/32] drm/amd/display: add plane 3D LUT driver-specific properties

2023-11-02 Thread Joshua Ashton

Also, Melissa, you cannot do:

if (!plane_state->color_mgmt_changed)
return 0;

in amdgpu_dm_plane_set_color_properties.

The allocation for dc_plane_state could be new and zero'ed so it needs 
to be set every time. (Until AMDGPU has better dedup'ing of stuff there)


The reason it looked like it worked for you now is because the duplicate 
was broken, so color mgmt for planes was always being marked as dirty there.


Thanks

- Joshie 🐸✨

On 11/2/23 03:48, Joshua Ashton wrote:



On 10/5/23 18:15, Melissa Wen wrote:

Add 3D LUT property for plane color transformations using a 3D lookup
table. 3D LUT allows for highly accurate and complex color
transformations and is suitable to adjust the balance between color
channels. It's also more complex to manage and require more
computational resources.

Since a 3D LUT has a limited number of entries in each dimension we want
to use them in an optimal fashion. This means using the 3D LUT in a
colorspace that is optimized for human vision, such as sRGB, PQ, or
another non-linear space. Therefore, userpace may need one 1D LUT
(shaper) before it to delinearize content and another 1D LUT after 3D
LUT (blend) to linearize content again for blending. The next patches
add these 1D LUTs to the plane color mgmt pipeline.

v3:
- improve commit message about 3D LUT
- describe the 3D LUT entries and size (Harry)

v4:
- advertise 3D LUT max size as the size of a single-dimension

Signed-off-by: Melissa Wen 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 18 +++
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  9 
  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 14 +++
  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 23 +++
  4 files changed, 64 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h

index 62044d41da75..f7adaa52c23f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -363,6 +363,24 @@ struct amdgpu_mode_info {
   * @plane_hdr_mult_property:
   */
  struct drm_property *plane_hdr_mult_property;
+    /**
+ * @plane_lut3d_property: Plane property for color transformation 
using

+ * a 3D LUT (pre-blending), a three-dimensional array where each
+ * element is an RGB triplet. Each dimension has a size of the cubed
+ * root of lut3d_size. The array contains samples from the 
approximated

+ * function. On AMD, values between samples are estimated by
+ * tetrahedral interpolation. The array is accessed with three 
indices,

+ * one for each input dimension (color channel), blue being the
+ * outermost dimension, red the innermost.
+ */
+    struct drm_property *plane_lut3d_property;
+    /**
+ * @plane_degamma_lut_size_property: Plane property to define the 
max
+ * size of 3D LUT as supported by the driver (read-only). The max 
size
+ * is the max size of one dimension and, therefore, the max 
number of

+ * entries for 3D LUT array is the 3D LUT size cubed;
+ */
+    struct drm_property *plane_lut3d_size_property;
  };
  #define AMDGPU_MAX_BL_LEVEL 0xFF
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h

index bb2ce843369d..7a2350c62cf1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -784,6 +784,11 @@ struct dm_plane_state {
   * TF is needed for any subsequent linear-to-non-linear transforms.
   */
  __u64 hdr_mult;
+    /**
+ * @lut3d: 3D lookup table blob. The blob (if not NULL) is an 
array of

+ * &struct drm_color_lut.
+ */
+    struct drm_property_blob *lut3d;
  };
  struct dm_crtc_state {
@@ -869,6 +874,10 @@ void amdgpu_dm_update_freesync_caps(struct 
drm_connector *connector,

  void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
+/* 3D LUT max size is 17x17x17 (4913 entries) */
+#define MAX_COLOR_3DLUT_SIZE 17
+#define MAX_COLOR_3DLUT_BITDEPTH 12
+/* 1D LUT size */
  #define MAX_COLOR_LUT_ENTRIES 4096
  /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
  #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c

index caf49a044ab4..011f2f9ec890 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -230,6 +230,20 @@ amdgpu_dm_create_color_properties(struct 
amdgpu_device *adev)

  return -ENOMEM;
  adev->mode_info.plane_hdr_mult_property = prop;
+    prop = drm_property_create(adev_to_drm(adev),
+   DRM_MODE_PROP_BLOB,
+   "AMD_PLANE_LUT3D", 0);
+    if (!prop)
+    return -ENOMEM;
+    adev->mode_info.plane_lut3d_property = prop;
+
+    prop = drm_property_create_range(adev_to_drm(adev),

Re: [PATCH 07/10] drm/tidss: Fix dss reset

2023-11-02 Thread Tomi Valkeinen

On 01/11/2023 16:30, Laurent Pinchart wrote:

Hi Tomi,

Thank you for the patch.

On Wed, Nov 01, 2023 at 11:17:44AM +0200, Tomi Valkeinen wrote:

The probe function calls dispc_softreset() before runtime PM is enabled
and without enabling any of the DSS clocks. This happens to work by
luck, and we need to make sure the DSS HW is active and the fclk is
enabled.

To fix the above, add a new function, dispc_init_hw(), which does:

- pm_runtime_set_active()
- clk_prepare_enable(fclk)
- dispc_softreset().

This ensures that the reset can be successfully accomplished.

Note that we use pm_runtime_set_active(), not the normal
pm_runtime_get(). The reason for this is that at this point we haven't
enabled the runtime PM yet and also we don't want the normal resume
callback to be called: the dispc resume callback does some initial HW
setup, and it expects that the HW was off (no video ports are
streaming). If the bootloader has enabled the DSS and has set up a
boot time splash-screen, the DSS would be enabled and streaming which
might lead to issues with the normal resume callback.


I think the right way to do this would be, in probe(), to

- power on the device
- enable runtime PM, masking the device as active
- at end of probe, calling pm_runtime_put_autosuspend()


Can you explain what that would accomplish, or why the code in this 
patch is wrong?


If I understand it right, you're suggesting a more "normal" power up at 
the probe time, and then leaving the DSS enabled, but with autosuspend. 
That would require powering up, doing a reset, and calling 
dispc_runtime_resume. Which can be done, but I'm not sure why it's 
better, as we're not interested in "normal" power up at probe time.


But I can see that my approach looks perhaps a bit odd just by looking 
at these patches. This work was related to keeping the bootloader's 
splash screen on the screen for a longer time, i.e. delaying reset.


For that, I wanted an early function (dispc_init_hw) which would, 
instead of always resetting the DSS as it does in this version, peek at 
the DSS hardware, and see if the DSS is already streaming. If no, do a 
reset and proceed normally. If yes, skip the reset, leave the clocks 
enabled, and keep DSS PM active.


Later, when we'd be doing the first modeset, the driver would do the 
initial reset.


So, that's why I wanted an independent function for the HW probing/init, 
which is called before runtime PM is enabled, and I did not want normal 
runtime resume to be called as dispc_runtime_resume() would break the 
display.


I think a better solution would be to set up the fb of tidss's fbdev to 
use the reserved memory, used for the boot splash screen. But I didn't 
figure out a way to do this. But even there we'd like to delay the reset 
until the first modeset (when the fbdev display is getting enabled).


 Tomi



Re: [PATCH v7 6/6] drm/i915/panelreplay: Debugfs support for panel replay

2023-11-02 Thread Hogander, Jouni
On Wed, 2023-10-11 at 16:39 +0530, Animesh Manna wrote:
> Add debugfs support which will print source and sink status
> per connector basis.

Sorry for late review. Noticed only by now that you have added this
patch into you set.

Can you please describe in commit message how you see the output of
debugfs interface will look like after your changes?

> 
> v1: Initial version. [rb-ed by Arun]
> v2: Added check for DP 2.0 and connector type in
> connector_debugfs_add().
> 
> Cc: Jouni Högander 
> Cc: Arun R Murthy 
> Cc: Jani Nikula 
> Signed-off-by: Animesh Manna 
> ---
>  drivers/gpu/drm/i915/display/intel_psr.c | 136 +
> --
>  1 file changed, 102 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 80de831c2f60..399fc0a8e636 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -2823,6 +2823,25 @@ static int
> psr_get_status_and_error_status(struct intel_dp *intel_dp,
> return 0;
>  }
>  
> +static int panel_replay_get_status_and_error_status(struct intel_dp
> *intel_dp,
> +   u8 *status, u8
> *error_status)
> +{
> +   struct drm_dp_aux *aux = &intel_dp->aux;
> +   int ret;
> +
> +   ret = drm_dp_dpcd_readb(aux,
> DP_SINK_DEVICE_PR_AND_FRAME_LOCK_STATUS, status);
> +   if (ret != 1)
> +   return ret;
> +
> +   ret = drm_dp_dpcd_readb(aux, DP_PANEL_REPLAY_ERROR_STATUS,
> error_status);
> +   if (ret != 1)
> +   return ret;
> +
> +   *status = *status & DP_PSR_SINK_STATE_MASK;
> +
> +   return 0;
> +}
> +

I think you should modify  psr_get_status_and_error_status instead of
duplicating most of it.

>  static void psr_alpm_check(struct intel_dp *intel_dp)
>  {
> struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> @@ -3035,7 +3054,7 @@ psr_source_status(struct intel_dp *intel_dp,
> struct seq_file *m)
> status = live_status[status_val];
> }
>  
> -   seq_printf(m, "Source PSR status: %s [0x%08x]\n", status,
> val);
> +   seq_printf(m, "Source PSR/PanelReplay status: %s [0x%08x]\n",
> status, val);
>  }
>  
>  static int intel_psr_status(struct seq_file *m, struct intel_dp
> *intel_dp)
> @@ -3048,18 +3067,23 @@ static int intel_psr_status(struct seq_file
> *m, struct intel_dp *intel_dp)
> bool enabled;
> u32 val;
>  
> -   seq_printf(m, "Sink support: %s", str_yes_no(psr-
> >sink_support));
> -   if (psr->sink_support)
> +   seq_printf(m, "Sink support: PSR = %s, Panel Replay = %s",
> +  str_yes_no(psr->sink_support),
> +  str_yes_no(psr->sink_panel_replay_support));
> +
> +   if (psr->sink_support || psr->sink_panel_replay_support)
> seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]);
> seq_puts(m, "\n");
>  
> -   if (!psr->sink_support)
> +   if (!(psr->sink_support || psr->sink_panel_replay_support))
> return 0;
>  
> wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> mutex_lock(&psr->lock);
>  
> -   if (psr->enabled)
> +   if (psr->panel_replay_enabled)
> +   status = "Panel Replay Enabled";
> +   else if (psr->enabled)
> status = psr->psr2_enabled ? "PSR2 enabled" : "PSR1
> enabled";
> else
> status = "disabled";
> @@ -3072,14 +3096,17 @@ static int intel_psr_status(struct seq_file
> *m, struct intel_dp *intel_dp)
> goto unlock;
> }
>  
> -   if (psr->psr2_enabled) {
> +   if (psr->panel_replay_enabled) {
> +   val = intel_de_read(dev_priv,
> TRANS_DP2_CTL(cpu_transcoder));
> +   enabled = val & TRANS_DP2_PANEL_REPLAY_ENABLE;
> +   } else if (psr->psr2_enabled) {
> val = intel_de_read(dev_priv,
> EDP_PSR2_CTL(cpu_transcoder));
> 
> enabled = val & EDP_PSR2_ENABLE;
> } else {
> val = intel_de_read(dev_priv, psr_ctl_reg(dev_priv,
> cpu_transcoder));
> enabled = val & EDP_PSR_ENABLE;
> }
> -   seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
> +   seq_printf(m, "Source PSR/PanelReplay ctl: %s [0x%08x]\n",
>    str_enabled_disabled(enabled), val);
> psr_source_status(intel_dp, m);
> seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
> @@ -3221,6 +3248,7 @@ static int i915_psr_sink_status_show(struct
> seq_file *m, void *data)
>  {
> struct intel_connector *connector = m->private;
> struct intel_dp *intel_dp = intel_attached_dp(connector);
> +   struct intel_psr *psr = &intel_dp->psr;
> static const char * const sink_status[] = {
> "inactive",
> "transition to active, capture and display",
> @@ -3231,45 +3259,82 @@ static int i915_psr_sink_status_show(str

[PATCH] drm/rect: only print the stack trace in drm_calc_scale() once

2023-11-02 Thread Dan Carpenter
The kunit test triggers this stack trace deliberately.  The
drm_rect_scale_cases[] test cases include a negative src and a negative
dst.  This ends up spamming the logs and can obscure real warnings.

Just print the warning once.

Reported-by: Linux Kernel Functional Testing 
Closes: 
https://lore.kernel.org/all/CA+G9fYuA643RHHpPnz9Ww7rr3zV5a0y=7_uFcybBSL=qp_s...@mail.gmail.com/
Signed-off-by: Dan Carpenter 
---
 drivers/gpu/drm/drm_rect.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c
index 85c79a38c13a..a992d70b928b 100644
--- a/drivers/gpu/drm/drm_rect.c
+++ b/drivers/gpu/drm/drm_rect.c
@@ -135,7 +135,7 @@ static int drm_calc_scale(int src, int dst)
 {
int scale = 0;
 
-   if (WARN_ON(src < 0 || dst < 0))
+   if (WARN_ON_ONCE(src < 0 || dst < 0))
return -EINVAL;
 
if (dst == 0)
-- 
2.42.0



Re: [PATCH 10/10] drm/tidss: Fix atomic_flush check

2023-11-02 Thread Tomi Valkeinen

On 01/11/2023 16:56, Laurent Pinchart wrote:

Hi Tomi,

Thank you for the patch.

On Wed, Nov 01, 2023 at 11:17:47AM +0200, Tomi Valkeinen wrote:

tidss_crtc_atomic_flush() checks if the crtc is enabled, and if not,
returns immediately as there's no reason to do any register changes.

However, the code checks for 'crtc->state->enable', which does not
reflect the actual HW state. We should instead look at the
'crtc->state->active' flag.

This causes the tidss_crtc_atomic_flush() to proceed with the flush even
if the active state is false, which then causes us to hit the
WARN_ON(!crtc->state->event) check.

Fix this by checking the active flag, and while at it, fix the related
debug print which had "active" and "needs modeset" wrong way.

Signed-off-by: Tomi Valkeinen 
---
  drivers/gpu/drm/tidss/tidss_crtc.c | 9 -
  1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c 
b/drivers/gpu/drm/tidss/tidss_crtc.c
index 5e5e466f35d1..4c7009a5d643 100644
--- a/drivers/gpu/drm/tidss/tidss_crtc.c
+++ b/drivers/gpu/drm/tidss/tidss_crtc.c
@@ -169,13 +169,12 @@ static void tidss_crtc_atomic_flush(struct drm_crtc *crtc,
struct tidss_device *tidss = to_tidss(ddev);
unsigned long flags;
  
-	dev_dbg(ddev->dev,

-   "%s: %s enabled %d, needs modeset %d, event %p\n", __func__,
-   crtc->name, drm_atomic_crtc_needs_modeset(crtc->state),
-   crtc->state->enable, crtc->state->event);
+   dev_dbg(ddev->dev, "%s: %s active %d, needs modeset %d, event %p\n",
+   __func__, crtc->name, crtc->state->active,
+   drm_atomic_crtc_needs_modeset(crtc->state), crtc->state->event);


While at it, how about this ?


Why not. The active part won't be needed if we use 
DRM_PLANE_COMMIT_ACTIVE_ONLY, though.



dev_dbg(ddev->dev, "%s: %s is %sactive, %s modeset, event %p\n",
__func__, crtc->name, crtc->state->active ? "" : "not ",
drm_atomic_crtc_needs_modeset(crtc->state) ? "needs", "doesn't 
need",
crtc->state->event);

  
  	/* There is nothing to do if CRTC is not going to be enabled. */

-   if (!crtc->state->enable)
+   if (!crtc->state->active)


I think the drm_atomic_helper_commit_planes() helper will handle this if
you pass it the DRM_PLANE_COMMIT_ACTIVE_ONLY flag.


I considered it, but it does a bit more, as it also affects the plane 
updates. We specifically did not use DRM_PLANE_COMMIT_ACTIVE_ONLY as it 
didn't work with DSS.


That said, I can't figure out what was the issue. It's possible the 
issue was only on the older DSS HW, with omapdrm (tidss code was 
originally somewhat based on omapdrm). I'm pretty sure the issue was 
related to multi-display systems and the plane updates there. But I 
don't have any multi-display board which uses tidss.


So, I'll keep this patch, but add another on top, which uses 
DRM_PLANE_COMMIT_ACTIVE_ONLY. Then it'll be easy to revert the 
DRM_PLANE_COMMIT_ACTIVE_ONLY one if needed, while still keeping this fix.


 Tomi



Re: [PATCH v8 3/5] drm/sched: Split free_job into own work item

2023-11-02 Thread Luben Tuikov
On 2023-10-30 23:24, Matthew Brost wrote:
> Rather than call free_job and run_job in same work item have a dedicated
> work item for each. This aligns with the design and intended use of work
> queues.
> 
> v2:
>- Test for DMA_FENCE_FLAG_TIMESTAMP_BIT before setting
>  timestamp in free_job() work item (Danilo)
> v3:
>   - Drop forward dec of drm_sched_select_entity (Boris)
>   - Return in drm_sched_run_job_work if entity NULL (Boris)
> v4:
>   - Replace dequeue with peek and invert logic (Luben)
>   - Wrap to 100 lines (Luben)
>   - Update comments for *_queue / *_queue_if_ready functions (Luben)
> v5:
>   - Drop peek argument, blindly reinit idle (Luben)
>   - s/drm_sched_free_job_queue_if_ready/drm_sched_free_job_queue_if_done 
> (Luben)
>   - Update work_run_job & work_free_job kernel doc (Luben)
> v6:
>   - Do not move drm_sched_select_entity in file (Luben)
> 
> Signed-off-by: Matthew Brost 

Reviewed-by: Luben Tuikov 

Regards,
Luben

> ---
>  drivers/gpu/drm/scheduler/sched_main.c | 146 +
>  include/drm/gpu_scheduler.h|   4 +-
>  2 files changed, 101 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> b/drivers/gpu/drm/scheduler/sched_main.c
> index d1ae05bded15..3b1b2f8eafe8 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -265,6 +265,32 @@ static void drm_sched_run_job_queue(struct 
> drm_gpu_scheduler *sched)
>   queue_work(sched->submit_wq, &sched->work_run_job);
>  }
>  
> +/**
> + * drm_sched_free_job_queue - enqueue free-job work
> + * @sched: scheduler instance
> + */
> +static void drm_sched_free_job_queue(struct drm_gpu_scheduler *sched)
> +{
> + if (!READ_ONCE(sched->pause_submit))
> + queue_work(sched->submit_wq, &sched->work_free_job);
> +}
> +
> +/**
> + * drm_sched_free_job_queue_if_done - enqueue free-job work if ready
> + * @sched: scheduler instance
> + */
> +static void drm_sched_free_job_queue_if_done(struct drm_gpu_scheduler *sched)
> +{
> + struct drm_sched_job *job;
> +
> + spin_lock(&sched->job_list_lock);
> + job = list_first_entry_or_null(&sched->pending_list,
> +struct drm_sched_job, list);
> + if (job && dma_fence_is_signaled(&job->s_fence->finished))
> + drm_sched_free_job_queue(sched);
> + spin_unlock(&sched->job_list_lock);
> +}
> +
>  /**
>   * drm_sched_job_done - complete a job
>   * @s_job: pointer to the job which is done
> @@ -284,7 +310,7 @@ static void drm_sched_job_done(struct drm_sched_job 
> *s_job, int result)
>   dma_fence_get(&s_fence->finished);
>   drm_sched_fence_finished(s_fence, result);
>   dma_fence_put(&s_fence->finished);
> - drm_sched_run_job_queue(sched);
> + drm_sched_free_job_queue(sched);
>  }
>  
>  /**
> @@ -943,8 +969,10 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler 
> *sched)
>   typeof(*next), list);
>  
>   if (next) {
> - next->s_fence->scheduled.timestamp =
> - dma_fence_timestamp(&job->s_fence->finished);
> + if (test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT,
> +  &next->s_fence->scheduled.flags))
> + next->s_fence->scheduled.timestamp =
> + 
> dma_fence_timestamp(&job->s_fence->finished);
>   /* start TO timer for next job */
>   drm_sched_start_timeout(sched);
>   }
> @@ -994,7 +1022,40 @@ drm_sched_pick_best(struct drm_gpu_scheduler 
> **sched_list,
>  EXPORT_SYMBOL(drm_sched_pick_best);
>  
>  /**
> - * drm_sched_run_job_work - main scheduler thread
> + * drm_sched_run_job_queue_if_ready - enqueue run-job work if ready
> + * @sched: scheduler instance
> + */
> +static void drm_sched_run_job_queue_if_ready(struct drm_gpu_scheduler *sched)
> +{
> + if (drm_sched_select_entity(sched))
> + drm_sched_run_job_queue(sched);
> +}
> +
> +/**
> + * drm_sched_free_job_work - worker to call free_job
> + *
> + * @w: free job work
> + */
> +static void drm_sched_free_job_work(struct work_struct *w)
> +{
> + struct drm_gpu_scheduler *sched =
> + container_of(w, struct drm_gpu_scheduler, work_free_job);
> + struct drm_sched_job *cleanup_job;
> +
> + if (READ_ONCE(sched->pause_submit))
> + return;
> +
> + cleanup_job = drm_sched_get_cleanup_job(sched);
> + if (cleanup_job) {
> + sched->ops->free_job(cleanup_job);
> +
> + drm_sched_free_job_queue_if_done(sched);
> + drm_sched_run_job_queue_if_ready(sched);
> + }
> +}
> +
> +/**
> + * drm_sched_run_job_work - worker to call run_job
>   *
>   * @w: run job work
>   */
> @@ -1003,65 +1064,51 @@ static void drm_sched_run_job_work(struct work_struct 
> *w)
>   struct drm_gpu_sched

Re: [PATCH] drm/i915/display: Only fail fastset on PSR2

2023-11-02 Thread Paz Zcharya
On Wed, Nov 01, 2023 at 06:26:47AM +, Hogander, Jouni wrote:
> On Tue, 2023-10-31 at 23:21 +, Paz Zcharya wrote:
> > Currently, i915 fails fastset if both the sink and the source support
> > any version of PSR and regardless of the configuration setting of the
> > driver (i.e., i915.enable_psr kernel argument). However, the
> > implementation of PSR1 enable sequence is already seamless
> > and works smoothly with fastset. Accordingly, do not fail fastset
> > if PSR2 is not enabled.
> 
> Thank you for the patch. Check similar patch I sent some time ago to
> trybot:
> 
> https://patchwork.freedesktop.org/series/125392/
> 

I missed this patch. I apologize!
This is great work and exactly what we (Google ChromeOS) need.
I think your patch is better than mine, so let's abort my patch
and continue the discussion at series/125392.

By the way, we have verified your patch on two Meteor Lake devices
running ChromeOS and it works smoothly (no flickering or modesets).
I'll comment on the other patch as well.

> If we want to temporarily do this only for psr1 I think you could check
> what I've done in drivers/gpu/drm/i915/display/intel_display.c in my
> patch and modify your patch accordingly. Otherwise e.g. our IGT
> testcases which are toggling PSR enable/disable/psr1/psr2 are to my
> understanding performing full modeset and possible issues are not
> revealed.
> 
> After modifying drivers/gpu/drm/i915/display/intel_display.c you can
> also verify it is really seamless and smooth by toggling different PSR
> states via /sys/kernel/debug/dri/0/i915_edp_psr_debug. That interface
> is performing atomic commit when PSR mode is changed.
> 
> BR,
> 
> Jouni Högander
> > 
> > Signed-off-by: Paz Zcharya 
> > ---
> > 
> >  drivers/gpu/drm/i915/display/intel_dp.c  | 4 ++--
> >  drivers/gpu/drm/i915/display/intel_psr.c | 2 +-
> >  drivers/gpu/drm/i915/display/intel_psr.h | 1 +
> >  3 files changed, 4 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> > b/drivers/gpu/drm/i915/display/intel_dp.c
> > index e0e4cb529284..a1af96e31518 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -2584,8 +2584,8 @@ bool intel_dp_initial_fastset_check(struct
> > intel_encoder *encoder,
> > fastset = false;
> > }
> >  
> > -   if (CAN_PSR(intel_dp)) {
> > -   drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full
> > modeset to compute PSR state\n",
> > +   if (CAN_PSR(intel_dp) && psr2_global_enabled(intel_dp)) {
> > +   drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full
> > modeset due to PSR2\n",
> >     encoder->base.base.id, encoder-
> > >base.name);
> > crtc_state->uapi.mode_changed = true;
> > fastset = false;
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > b/drivers/gpu/drm/i915/display/intel_psr.c
> > index 97d5eef10130..388bc3246db9 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > @@ -187,7 +187,7 @@ static bool psr_global_enabled(struct intel_dp
> > *intel_dp)
> > }
> >  }
> >  
> > -static bool psr2_global_enabled(struct intel_dp *intel_dp)
> > +bool psr2_global_enabled(struct intel_dp *intel_dp)
> >  {
> > struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.h
> > b/drivers/gpu/drm/i915/display/intel_psr.h
> > index 0b95e8aa615f..6f3c36389cd3 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.h
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> > @@ -21,6 +21,7 @@ struct intel_encoder;
> >  struct intel_plane;
> >  struct intel_plane_state;
> >  
> > +bool psr2_global_enabled(struct intel_dp *intel_dp);
> >  void intel_psr_init_dpcd(struct intel_dp *intel_dp);
> >  void intel_psr_pre_plane_update(struct intel_atomic_state *state,
> > struct intel_crtc *crtc);
> 

.


[BUG] gpu: drm: amd: noretry=0 causes failure in amdgpu_device_ip_resume on vega10

2023-11-02 Thread Carl Klemm
Hi,

When migrateing from 5.15 to 6.5.9 i noticed that noretry no longer
function on vega10 (Instinct MI25). The device will fail to start:

[   40.080411] amdgpu: fw load failed
[   40.083816] amdgpu: smu firmware loading failed
[   40.088350] amdgpu :83:00.0: amdgpu: amdgpu_device_ip_resume
failed (-22).

I have also repoduced the same issue on 6.1.55
It is also possible that the issue was caused by newer gpu firmware,
instead of the change in kernel. The issue was repduced with the
firmware from linux-firmware-20230804.

for full dmesg see: https://uvos.xyz/noretry.dmesg.log

The same system also contains 2 vega20 and 1 navi21 device that both
work fine with noretry=0. For more information on the system this
problem was encountered on see this rocminfo dump:
https://uvos.xyz/rocminfo.log

Regards,
Carl


Re: [PATCH v8 0/5] DRM scheduler changes for Xe

2023-11-02 Thread Luben Tuikov
On 2023-10-30 23:24, Matthew Brost wrote:
>   As a prerequisite to merging the new Intel Xe DRM driver [1] [2], we
> have been asked to merge our common DRM scheduler patches first.
> 
> This a continuation of a RFC [3] with all comments addressed, ready for
> a full review, and hopefully in state which can merged in the near
> future. More details of this series can found in the cover letter of the
> RFC [3].
> 
> These changes have been tested with the Xe driver. Based on drm-tip branch.
> 
> A follow up series will be posted to address some of dakr requets for
> kernel doc changes.
> 
> v2:
>  - Break run job, free job, and process message in own work items
>  - This might break other drivers as run job and free job now can run in
>parallel, can fix up if needed
> 
> v3:
>  - Include missing patch 'drm/sched: Add drm_sched_submit_* helpers'
>  - Fix issue with setting timestamp to early
>  - Don't dequeue jobs for single entity after calling entity fini
>  - Flush pending jobs on entity fini
>  - Add documentation for entity teardown
>  - Add Matthew Brost to maintainers of DRM scheduler
> 
> v4:
>  - Drop message interface
>  - Drop 'Flush pending jobs on entity fini'
>  - Drop 'Add documentation for entity teardown'
>  - Address all feedback
> 
> v5:
>  - Address Luben's feedback
>  - Drop starting TDR after calling run_job()
>  - Drop adding Matthew Brost to maintainers of DRM scheduler
> 
> v6:
>  - Address Luben's feedback
>  - Include base commit
> 
> v7:
>  - Drop SINGLE_ENTITY mode rather pull in Luben's patch for dynamic run queues
>  - Address Luben's feedback for free_job work item patch
> 
> v8:
>  - Rebase on drm-tip which includes Luben's patch for dynamic run queues
>  - Don't adjust comments, change variable names, function names twice in 
> series
>  - Don't move existing code to different places in a file to preserve git 
> history
> 
> Matt
> 
> [1] https://gitlab.freedesktop.org/drm/xe/kernel
> [2] https://patchwork.freedesktop.org/series/112188/
> [3] https://patchwork.freedesktop.org/series/116055/
> 
> Matthew Brost (5):
>   drm/sched: Add drm_sched_wqueue_* helpers
>   drm/sched: Convert drm scheduler to use a work queue rather than
> kthread
>   drm/sched: Split free_job into own work item
>   drm/sched: Add drm_sched_start_timeout_unlocked helper
>   drm/sched: Add a helper to queue TDR immediately
> 
>  .../drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c   |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c   |  15 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c|  14 +-
>  drivers/gpu/drm/etnaviv/etnaviv_sched.c   |   2 +-
>  drivers/gpu/drm/lima/lima_sched.c |   2 +-
>  drivers/gpu/drm/msm/adreno/adreno_device.c|   6 +-
>  drivers/gpu/drm/msm/msm_ringbuffer.c  |   2 +-
>  drivers/gpu/drm/nouveau/nouveau_sched.c   |   2 +-
>  drivers/gpu/drm/panfrost/panfrost_job.c   |   2 +-
>  drivers/gpu/drm/scheduler/sched_main.c| 301 --
>  drivers/gpu/drm/v3d/v3d_sched.c   |  10 +-
>  include/drm/gpu_scheduler.h   |  20 +-
>  12 files changed, 248 insertions(+), 130 deletions(-)
> 
> 
> base-commit: b560681c6bf623db41064ac486dd148d6c103e53

Hi Matthew,

I've pushed this series into drm-misc-next--I've tested and am running live 
with it.
Make sure to use "dim update-branches" to get all the resolutions, etc.

Thank you for working through this. Have a nice rest of your week. :-)
-- 
Regards,
Luben


OpenPGP_0x521A33F7270C04E6.asc
Description: OpenPGP public key


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH] drm/edid: add a quirk for two 240Hz Samsung monitors

2023-11-02 Thread Jani Nikula
On Wed, 01 Nov 2023, Alex Deucher  wrote:
> On Wed, Nov 1, 2023 at 5:01 PM Hamza Mahfooz  wrote:
>>
>> Without this fix the 5120x1440@240 timing of these monitors
>> leads to screen flickering.
>>
>> Cc: sta...@vger.kernel.org # 6.1+
>> Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1442
>> Co-developed-by: Harry Wentland 
>> Signed-off-by: Harry Wentland 
>> Signed-off-by: Hamza Mahfooz 
>> ---
>>  drivers/gpu/drm/drm_edid.c | 47 +++---
>>  1 file changed, 44 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index bca2af4fe1fc..3fdb8907f66b 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -89,6 +89,8 @@ static int oui(u8 first, u8 second, u8 third)
>>  #define EDID_QUIRK_NON_DESKTOP (1 << 12)
>>  /* Cap the DSC target bitrate to 15bpp */
>>  #define EDID_QUIRK_CAP_DSC_15BPP   (1 << 13)
>> +/* Fix up a particular 5120x1440@240Hz timing */
>> +#define EDID_QUIRK_FIXUP_5120_1440_240 (1 << 14)
>
> What is wrong with the original timing that needs to be fixed?

Indeed. I'd be wary of applying this quirk as-is, because it'll impact
all drivers and all connectors.

The bug report does not have a single EDID from the affected displays
attached.

The quirk sets mode members that apparently do not need to be modified.

Cc: Ville


BR,
Jani.


>
> Alex
>
>
>>
>>  #define MICROSOFT_IEEE_OUI 0xca125c
>>
>> @@ -170,6 +172,12 @@ static const struct edid_quirk {
>> EDID_QUIRK('S', 'A', 'M', 596, EDID_QUIRK_PREFER_LARGE_60),
>> EDID_QUIRK('S', 'A', 'M', 638, EDID_QUIRK_PREFER_LARGE_60),
>>
>> +   /* Samsung C49G95T */
>> +   EDID_QUIRK('S', 'A', 'M', 0x7053, EDID_QUIRK_FIXUP_5120_1440_240),
>> +
>> +   /* Samsung S49AG95 */
>> +   EDID_QUIRK('S', 'A', 'M', 0x71ac, EDID_QUIRK_FIXUP_5120_1440_240),
>> +
>> /* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */
>> EDID_QUIRK('S', 'N', 'Y', 0x2541, EDID_QUIRK_FORCE_12BPC),
>>
>> @@ -6586,7 +6594,37 @@ static void update_display_info(struct drm_connector 
>> *connector,
>> drm_edid_to_eld(connector, drm_edid);
>>  }
>>
>> -static struct drm_display_mode *drm_mode_displayid_detailed(struct 
>> drm_device *dev,
>> +static void drm_mode_displayid_detailed_edid_quirks(struct drm_connector 
>> *connector,
>> +   struct drm_display_mode 
>> *mode)
>> +{
>> +   unsigned int hsync_width;
>> +   unsigned int vsync_width;
>> +
>> +   if (connector->display_info.quirks & EDID_QUIRK_FIXUP_5120_1440_240) 
>> {
>> +   if (mode->hdisplay == 5120 && mode->vdisplay == 1440 &&
>> +   mode->clock == 1939490) {
>> +   hsync_width = mode->hsync_end - mode->hsync_start;
>> +   vsync_width = mode->vsync_end - mode->vsync_start;
>> +
>> +   mode->clock = 2018490;
>> +   mode->hdisplay = 5120;
>> +   mode->hsync_start = 5120 + 8;
>> +   mode->hsync_end = 5120 + 8 + hsync_width;
>> +   mode->htotal = 5200;
>> +
>> +   mode->vdisplay = 1440;
>> +   mode->vsync_start = 1440 + 165;
>> +   mode->vsync_end = 1440 + 165 + vsync_width;
>> +   mode->vtotal = 1619;
>> +
>> +   drm_dbg_kms(connector->dev,
>> +   "[CONNECTOR:%d:%s] Samsung 240Hz mode 
>> quirk applied\n",
>> +   connector->base.id, connector->name);
>> +   }
>> +   }
>> +}
>> +
>> +static struct drm_display_mode *drm_mode_displayid_detailed(struct 
>> drm_connector *connector,
>> struct 
>> displayid_detailed_timings_1 *timings,
>> bool type_7)
>>  {
>> @@ -6605,7 +6643,7 @@ static struct drm_display_mode 
>> *drm_mode_displayid_detailed(struct drm_device *d
>> bool hsync_positive = (timings->hsync[1] >> 7) & 0x1;
>> bool vsync_positive = (timings->vsync[1] >> 7) & 0x1;
>>
>> -   mode = drm_mode_create(dev);
>> +   mode = drm_mode_create(connector->dev);
>> if (!mode)
>> return NULL;
>>
>> @@ -6628,6 +,9 @@ static struct drm_display_mode 
>> *drm_mode_displayid_detailed(struct drm_device *d
>>
>> if (timings->flags & 0x80)
>> mode->type |= DRM_MODE_TYPE_PREFERRED;
>> +
>> +   drm_mode_displayid_detailed_edid_quirks(connector, mode);
>> +
>> drm_mode_set_name(mode);
>>
>> return mode;
>> @@ -6650,7 +6691,7 @@ static int add_displayid_detailed_1_modes(struct 
>> drm_connector *connector,
>> for (i = 0; i < num_timings; i++) {
>> struct displayid_detailed_timings_1 *timings = 

Re: [PATCH] drm/i915: Remove unused for_each_uabi_class_engine

2023-11-02 Thread Jani Nikula
On Wed, 01 Nov 2023, Tvrtko Ursulin  wrote:
> On 01/11/2023 10:06, Jani Nikula wrote:
>> On Wed, 01 Nov 2023, Tvrtko Ursulin  wrote:
>>> From: Tvrtko Ursulin 
>>>
>>> Unused macro after 99919be74aa3 ("drm/i915/gem: Zap the i915_gem_object_blt 
>>> code")
>>> removed some code.
>>>
>>> Signed-off-by: Tvrtko Ursulin 
>> 
>> \o/
>> 
>> Reviewed-by: Jani Nikula 
>> 
>> Could I persuade you to move for_each_engine(),
>> for_each_engine_masked(), rb_to_uabi_engine(), and
>> for_each_uabi_engine() to a more suitable header?
>
> Former to intel_gt.h, but latter a better place is not coming to me. Like:
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.h 
> b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
> index d68675925b79..1d97c435a015 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_pm.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
> @@ -10,6 +10,7 @@
>   #include "i915_request.h"
>   #include "intel_engine_types.h"
>   #include "intel_wakeref.h"
> +#include "intel_gt.h"
>   #include "intel_gt_pm.h"
>   
>   static inline bool
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
> b/drivers/gpu/drm/i915/gt/intel_gt.h
> index 9ffdb05e231e..b0e453e27ea8 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.h
> @@ -171,6 +171,20 @@ void intel_gt_release_all(struct drm_i915_private *i915);
>   (id__)++) \
>  for_each_if(((gt__) = (i915__)->gt[(id__)]))
>   
> +/* Simple iterator over all initialised engines */
> +#define for_each_engine(engine__, gt__, id__) \
> +   for ((id__) = 0; \
> +(id__) < I915_NUM_ENGINES; \
> +(id__)++) \
> +   for_each_if ((engine__) = (gt__)->engine[(id__)])
> +
> +/* Iterator over subset of engines selected by mask */
> +#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
> +   for ((tmp__) = (mask__) & (gt__)->info.engine_mask; \
> +(tmp__) ? \
> +((engine__) = (gt__)->engine[__mask_next_bit(tmp__)]), 1 : \
> +0;)
> +
>   void intel_gt_info_print(const struct intel_gt_info *info,
>   struct drm_printer *p);
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c 
> b/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
> index 8f9b874fdc9c..3aa1d014c14d 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
> @@ -6,8 +6,8 @@
>   
>   #include 
>   
> -#include "i915_drv.h" /* for_each_engine! */
>   #include "intel_engine.h"
> +#include "intel_gt.h"
>   #include "intel_gt_debugfs.h"
>   #include "intel_gt_engines_debugfs.h"
>   
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 744c8c4a50fa..3feec04a2b1c 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -396,20 +396,6 @@ static inline struct intel_gt *to_gt(const struct 
> drm_i915_private *i915)
>  return i915->gt[0];
>   }
>   
> -/* Simple iterator over all initialised engines */
> -#define for_each_engine(engine__, gt__, id__) \
> -   for ((id__) = 0; \
> -(id__) < I915_NUM_ENGINES; \
> -(id__)++) \
> -   for_each_if ((engine__) = (gt__)->engine[(id__)])
> -
> -/* Iterator over subset of engines selected by mask */
> -#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
> -   for ((tmp__) = (mask__) & (gt__)->info.engine_mask; \
> -(tmp__) ? \
> -((engine__) = (gt__)->engine[__mask_next_bit(tmp__)]), 1 : \
> -0;)
> -
>   #define rb_to_uabi_engine(rb) \
>  rb_entry_safe(rb, struct intel_engine_cs, uabi_node)
>   
> diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c 
> b/drivers/gpu/drm/i915/selftests/intel_uncore.c
> index 7a5f4adc1b8b..c998f15d505c 100644
> --- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
> @@ -24,6 +24,8 @@
>   
>   #include "../i915_selftest.h"
>   
> +#include "gt/intel_gt.h"
> +
>   static int intel_fw_table_check(const struct intel_forcewake_range *ranges,
>  unsigned int num_ranges,
>  bool is_watertight)
>
> Beneficial?

Yeah, I'd like to have less gem/gt/display in i915_drv.h, and focus on
the generic driver stuff.

BR,
Jani.


>
> Regards,
>
> Tvrtko
>   
>>> ---
>>>   drivers/gpu/drm/i915/i915_drv.h | 5 -
>>>   1 file changed, 5 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h 
>>> b/drivers/gpu/drm/i915/i915_drv.h
>>> index bfcbe93bd9fe..744c8c4a50fa 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -418,11 +418,6 @@ static inline struct intel_gt *to_gt(const struct 
>>> drm_i915_private *i915)
>>>  (engine__); \
>>>  (engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
>>>   
>>> -#define for_each_uabi_class_engine(engine__, clas

Re: [accel/ivpu] Help -- Which Intel CPU processor can be used for iVPU driver?

2023-11-02 Thread Jacek Lawrynowicz
Hi,

You need a Meteor Lake based platform.
Intel 14th gen desktop CPUs were supposed to be Meteor Lake but they ended up 
as Raptor Lake.
NPU (formerly known as VPU) will be available in 14th gen mobile chips.
I will update the Kconfig description.

Regards,
Jacek

On 02.11.2023 07:59, Trigger Huang wrote:
> Hello,
> 
> I want to have a try for the iVPU driver but don't know which CPU platform
> is suitable. Would you help?
> 
> According to the description in linux/drivers/accel/ivpu/Kconfig, it says
> that Choose this option if you have a system that has an *14*th generation
> Intel CPU
> But according to the Intel  I7 *14*700k spec (
> https://www.intel.com/content/www/us/en/products/sku/236783/intel-core-i7-processor-14700k-33m-cache-up-to-5-60-ghz/specifications.html),
> there is
> no description about Versatile Processing Unit.
> 
> So which CPU should I choose?
> 
> Thanks,
> Trigger
> 


mainline build failure due to 7966f319c66d ("drm/amd/display: Introduce DML2")

2023-11-02 Thread Sudip Mukherjee (Codethink)
Hi All,

The latest mainline kernel branch fails to build x86_64 allmodconfig
with the error:

drivers/gpu/drm/amd/amdgpu/../display/dc/dml2/display_mode_core.c: In function 
'dml_prefetch_check':
drivers/gpu/drm/amd/amdgpu/../display/dc/dml2/display_mode_core.c:6707:1: 
error: the frame size of 2056 bytes is larger than 2048 bytes 
[-Werror=frame-larger-than=]
 6707 | }
  | ^

git bisect pointed to 7966f319c66d ("drm/amd/display: Introduce DML2")

I will be happy to test any patch or provide any extra log if needed.

#regzbot introduced: 7966f319c66d9468623c6a6a017ecbc0dd79be75

-- 
Regards
Sudip


[PATCH 1/2] drm/i915: Remove unused for_each_uabi_class_engine

2023-11-02 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Unused macro after 99919be74aa3 ("drm/i915/gem: Zap the i915_gem_object_blt 
code")
removed some code.

Signed-off-by: Tvrtko Ursulin 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/i915_drv.h | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 259884b10d9a..bf6ed434bb6b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -418,11 +418,6 @@ static inline struct intel_gt *to_gt(const struct 
drm_i915_private *i915)
 (engine__); \
 (engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
 
-#define for_each_uabi_class_engine(engine__, class__, i915__) \
-   for ((engine__) = intel_engine_lookup_user((i915__), (class__), 0); \
-(engine__) && (engine__)->uabi_class == (class__); \
-(engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
-
 #define INTEL_INFO(i915)   ((i915)->__info)
 #define RUNTIME_INFO(i915) (&(i915)->__runtime)
 #define DRIVER_CAPS(i915)  (&(i915)->caps)
-- 
2.39.2



[PATCH 2/2] drm/i915: Move for_each_engine* out of i915_drv.h

2023-11-02 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Iterators operate on struct intel_gt so lets move it to intel_gt.h in
order to make i915_drv.h less of a dumping ground for stuff.

Signed-off-by: Tvrtko Ursulin 
Suggested-by: Jani Nikula 
---
 drivers/gpu/drm/i915/gt/intel_engine_pm.h  |  1 +
 drivers/gpu/drm/i915/gt/intel_gt.h | 14 ++
 drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c |  2 +-
 drivers/gpu/drm/i915/i915_drv.h| 14 --
 drivers/gpu/drm/i915/selftests/intel_uncore.c  |  2 ++
 5 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.h 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
index d68675925b79..1d97c435a015 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
@@ -10,6 +10,7 @@
 #include "i915_request.h"
 #include "intel_engine_types.h"
 #include "intel_wakeref.h"
+#include "intel_gt.h"
 #include "intel_gt_pm.h"
 
 static inline bool
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
b/drivers/gpu/drm/i915/gt/intel_gt.h
index 9ffdb05e231e..b0e453e27ea8 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -171,6 +171,20 @@ void intel_gt_release_all(struct drm_i915_private *i915);
 (id__)++) \
for_each_if(((gt__) = (i915__)->gt[(id__)]))
 
+/* Simple iterator over all initialised engines */
+#define for_each_engine(engine__, gt__, id__) \
+   for ((id__) = 0; \
+(id__) < I915_NUM_ENGINES; \
+(id__)++) \
+   for_each_if ((engine__) = (gt__)->engine[(id__)])
+
+/* Iterator over subset of engines selected by mask */
+#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
+   for ((tmp__) = (mask__) & (gt__)->info.engine_mask; \
+(tmp__) ? \
+((engine__) = (gt__)->engine[__mask_next_bit(tmp__)]), 1 : \
+0;)
+
 void intel_gt_info_print(const struct intel_gt_info *info,
 struct drm_printer *p);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c 
b/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
index 8f9b874fdc9c..3aa1d014c14d 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
@@ -6,8 +6,8 @@
 
 #include 
 
-#include "i915_drv.h" /* for_each_engine! */
 #include "intel_engine.h"
+#include "intel_gt.h"
 #include "intel_gt_debugfs.h"
 #include "intel_gt_engines_debugfs.h"
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bf6ed434bb6b..f3be9033a93f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -396,20 +396,6 @@ static inline struct intel_gt *to_gt(const struct 
drm_i915_private *i915)
return i915->gt[0];
 }
 
-/* Simple iterator over all initialised engines */
-#define for_each_engine(engine__, gt__, id__) \
-   for ((id__) = 0; \
-(id__) < I915_NUM_ENGINES; \
-(id__)++) \
-   for_each_if ((engine__) = (gt__)->engine[(id__)])
-
-/* Iterator over subset of engines selected by mask */
-#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
-   for ((tmp__) = (mask__) & (gt__)->info.engine_mask; \
-(tmp__) ? \
-((engine__) = (gt__)->engine[__mask_next_bit(tmp__)]), 1 : \
-0;)
-
 #define rb_to_uabi_engine(rb) \
rb_entry_safe(rb, struct intel_engine_cs, uabi_node)
 
diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c 
b/drivers/gpu/drm/i915/selftests/intel_uncore.c
index 03ea75cd84dd..4f98aa8a861e 100644
--- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
+++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -24,6 +24,8 @@
 
 #include "../i915_selftest.h"
 
+#include "gt/intel_gt.h"
+
 static int intel_fw_table_check(const struct intel_forcewake_range *ranges,
unsigned int num_ranges,
bool is_watertight)
-- 
2.39.2



Re: [PATCH v2 0/6] drm/edid: split out drm_eld.[ch], add some SAD helpers

2023-11-02 Thread Jani Nikula
On Tue, 31 Oct 2023, Jani Nikula  wrote:
> v2 of https://patchwork.freedesktop.org/series/123384/
>
> Jani Nikula (6):
>   drm/edid: split out drm_eld.h from drm_edid.h
>   drm/eld: replace uint8_t with u8
>   drm/edid: include drm_eld.h only where required
>   drm/edid: use a temp variable for sads to drop one level of
> dereferences
>   drm/edid: add helpers to get/set struct cea_sad from/to 3-byte sad
>   drm/eld: add helpers to modify the SADs of an ELD

Maxime, Maarten, Thomas -

I'm moving a bunch of code around here, and would like to get your acks
before merging. I'm planning on merging this via drm-misc-next, it's
just that it only has Intel reviews, and don't want to feel like I'm
sneaking this in.

Thanks,
Jani.

>
>  Documentation/gpu/drm-kms-helpers.rst |   6 +
>  drivers/gpu/drm/Makefile  |   1 +
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   1 +
>  drivers/gpu/drm/drm_edid.c|  43 +++--
>  drivers/gpu/drm/drm_eld.c |  55 ++
>  drivers/gpu/drm/drm_internal.h|   6 +
>  drivers/gpu/drm/i915/display/intel_audio.c|   1 +
>  .../drm/i915/display/intel_crtc_state_dump.c  |   1 +
>  drivers/gpu/drm/i915/display/intel_sdvo.c |   1 +
>  drivers/gpu/drm/nouveau/dispnv50/disp.c   |   1 +
>  drivers/gpu/drm/radeon/radeon_audio.c |   1 +
>  drivers/gpu/drm/tegra/hdmi.c  |   1 +
>  drivers/gpu/drm/tegra/sor.c   |   1 +
>  include/drm/drm_edid.h| 148 
>  include/drm/drm_eld.h | 164 ++
>  sound/core/pcm_drm_eld.c  |   1 +
>  sound/soc/codecs/hdac_hdmi.c  |   1 +
>  sound/soc/codecs/hdmi-codec.c |   1 +
>  sound/x86/intel_hdmi_audio.c  |   1 +
>  19 files changed, 275 insertions(+), 160 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_eld.c
>  create mode 100644 include/drm/drm_eld.h

-- 
Jani Nikula, Intel


Re: [PATCH] drm/i915: Remove unused for_each_uabi_class_engine

2023-11-02 Thread Tvrtko Ursulin



On 02/11/2023 09:24, Jani Nikula wrote:

On Wed, 01 Nov 2023, Tvrtko Ursulin  wrote:

On 01/11/2023 10:06, Jani Nikula wrote:

On Wed, 01 Nov 2023, Tvrtko Ursulin  wrote:

From: Tvrtko Ursulin 

Unused macro after 99919be74aa3 ("drm/i915/gem: Zap the i915_gem_object_blt 
code")
removed some code.

Signed-off-by: Tvrtko Ursulin 


\o/

Reviewed-by: Jani Nikula 

Could I persuade you to move for_each_engine(),
for_each_engine_masked(), rb_to_uabi_engine(), and
for_each_uabi_engine() to a more suitable header?


Former to intel_gt.h, but latter a better place is not coming to me. Like:

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.h 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
index d68675925b79..1d97c435a015 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
@@ -10,6 +10,7 @@
   #include "i915_request.h"
   #include "intel_engine_types.h"
   #include "intel_wakeref.h"
+#include "intel_gt.h"
   #include "intel_gt_pm.h"
   
   static inline bool

diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
b/drivers/gpu/drm/i915/gt/intel_gt.h
index 9ffdb05e231e..b0e453e27ea8 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -171,6 +171,20 @@ void intel_gt_release_all(struct drm_i915_private *i915);
   (id__)++) \
  for_each_if(((gt__) = (i915__)->gt[(id__)]))
   
+/* Simple iterator over all initialised engines */

+#define for_each_engine(engine__, gt__, id__) \
+   for ((id__) = 0; \
+(id__) < I915_NUM_ENGINES; \
+(id__)++) \
+   for_each_if ((engine__) = (gt__)->engine[(id__)])
+
+/* Iterator over subset of engines selected by mask */
+#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
+   for ((tmp__) = (mask__) & (gt__)->info.engine_mask; \
+(tmp__) ? \
+((engine__) = (gt__)->engine[__mask_next_bit(tmp__)]), 1 : \
+0;)
+
   void intel_gt_info_print(const struct intel_gt_info *info,
   struct drm_printer *p);
   
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c b/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c

index 8f9b874fdc9c..3aa1d014c14d 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
@@ -6,8 +6,8 @@
   
   #include 
   
-#include "i915_drv.h" /* for_each_engine! */

   #include "intel_engine.h"
+#include "intel_gt.h"
   #include "intel_gt_debugfs.h"
   #include "intel_gt_engines_debugfs.h"
   
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h

index 744c8c4a50fa..3feec04a2b1c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -396,20 +396,6 @@ static inline struct intel_gt *to_gt(const struct 
drm_i915_private *i915)
  return i915->gt[0];
   }
   
-/* Simple iterator over all initialised engines */

-#define for_each_engine(engine__, gt__, id__) \
-   for ((id__) = 0; \
-(id__) < I915_NUM_ENGINES; \
-(id__)++) \
-   for_each_if ((engine__) = (gt__)->engine[(id__)])
-
-/* Iterator over subset of engines selected by mask */
-#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
-   for ((tmp__) = (mask__) & (gt__)->info.engine_mask; \
-(tmp__) ? \
-((engine__) = (gt__)->engine[__mask_next_bit(tmp__)]), 1 : \
-0;)
-
   #define rb_to_uabi_engine(rb) \
  rb_entry_safe(rb, struct intel_engine_cs, uabi_node)
   
diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c b/drivers/gpu/drm/i915/selftests/intel_uncore.c

index 7a5f4adc1b8b..c998f15d505c 100644
--- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
+++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -24,6 +24,8 @@
   
   #include "../i915_selftest.h"
   
+#include "gt/intel_gt.h"

+
   static int intel_fw_table_check(const struct intel_forcewake_range *ranges,
  unsigned int num_ranges,
  bool is_watertight)

Beneficial?


Yeah, I'd like to have less gem/gt/display in i915_drv.h, and focus on
the generic driver stuff.


Okay, sent.

For for_each_uabi_engine&co problem is how do we define what is what. 
Historically we weren't saying that everything not display is GEM, and 
uabi engines are not per GT. Even though engines themselves are, just 
that historically we were putting stuff into GT which operates on a GT. 
Perhaps with factoring out the display goal the requirements change a 
bit and old boundaries/placement rules need tweaking. Or the sore point 
will go away as/when display code is better isolated (less hacks, more 
interfaces) from both i915 and xe. Anyway, for now I don't see a nice 
and easy place to move them to, which wouldn't be wrong from some aspect.


Regards,

Tvrtko


Re: [PATCH 1/7] drm: Do not round to megabytes for greater than 1MiB sizes in fdinfo stats

2023-11-02 Thread Tvrtko Ursulin



On 26/10/2023 15:43, Tvrtko Ursulin wrote:


On 28/09/2023 13:47, Tvrtko Ursulin wrote:


On 27/09/2023 14:48, Steven Price wrote:

On 27/09/2023 14:38, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

It is better not to lose precision and not revert to 1 MiB size
granularity for every size greater than 1 MiB.

Sizes in KiB should not be so troublesome to read (and in fact machine
parsing is I expect the norm here), they align with other api like
/proc/meminfo, and they allow writing tests for the interface without
having to embed drm.ko implementation knowledge into them. (Like 
knowing
that minimum buffer size one can use for successful verification has 
to be
1MiB aligned, and on top account for any pre-existing memory 
utilisation

outside of driver's control.)

But probably even more importantly I think that it is just better to 
show
the accurate sizes and not arbitrary lose precision for a little bit 
of a

stretched use case of eyeballing fdinfo text directly.

Signed-off-by: Tvrtko Ursulin 
Cc: Rob Clark 
Cc: Adrián Larumbe 
Cc: steven.pr...@arm.com


Reviewed-by: Steven Price 


Thanks! Rob? Can we have your blessing? Could you live with KiBs? :)


Acked received on #dri-devel:

[12:15]  robclark: ping on 
https://lists.freedesktop.org/archives/dri-devel/2023-September/424905.html - can you live with it or object?

[14:41]  tursulin: a-b

Adding the drm-misc maintainers with an ask to merge please.


Ping please - just this one patch to merge to drm-misc-next if possible.

Regards,

Tvrtko


[PATCH] drm/i915: Fix potential spectre vulnerability

2023-11-02 Thread chentao
Fix smatch warning:
drivers/gpu/drm/i915/gem/i915_gem_context.c:847 set_proto_ctx_sseu()
warn: potential spectre issue 'pc->user_engines' [r] (local cap)

Signed-off-by: chentao 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 9a9ff84c90d7..b2fdfc7ca4de 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -843,7 +843,7 @@ static int set_proto_ctx_sseu(struct drm_i915_file_private 
*fpriv,
 
if (idx >= pc->num_user_engines)
return -EINVAL;
-
+   idx = array_index_nospec(idx, pc->num_user_engines);
pe = &pc->user_engines[idx];
 
/* Only render engine supports RPCS configuration. */
-- 
2.34.1



Re: [PATCH drm-misc-next v8 09/12] drm/gpuvm: reference count drm_gpuvm structures

2023-11-02 Thread kernel test robot
Hi Danilo,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 3c6c7ca4508b6cb1a033ac954c50a1b2c97af883]

url:
https://github.com/intel-lab-lkp/linux/commits/Danilo-Krummrich/drm-gpuvm-convert-WARN-to-drm_WARN-variants/20231102-073332
base:   3c6c7ca4508b6cb1a033ac954c50a1b2c97af883
patch link:
https://lore.kernel.org/r/20231101233113.8059-10-dakr%40redhat.com
patch subject: [PATCH drm-misc-next v8 09/12] drm/gpuvm: reference count 
drm_gpuvm structures
config: arc-allmodconfig 
(https://download.01.org/0day-ci/archive/20231102/202311021833.q8aydjnr-...@intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231102/202311021833.q8aydjnr-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202311021833.q8aydjnr-...@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/drm_gpuvm.c:810: warning: expecting prototype for 
>> drm_gpuvm_bo_put(). Prototype was for drm_gpuvm_put() instead


vim +810 drivers/gpu/drm/drm_gpuvm.c

   801  
   802  /**
   803   * drm_gpuvm_bo_put() - drop a struct drm_gpuvm reference
   804   * @gpuvm: the &drm_gpuvm to release the reference of
   805   *
   806   * This releases a reference to @gpuvm.
   807   */
   808  void
   809  drm_gpuvm_put(struct drm_gpuvm *gpuvm)
 > 810  {
   811  if (gpuvm)
   812  kref_put(&gpuvm->kref, drm_gpuvm_free);
   813  }
   814  EXPORT_SYMBOL_GPL(drm_gpuvm_put);
   815  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


Re: [PATCH 2/3] drm/scheduler: Fix UAF in drm_sched_fence_get_timeline_name

2023-11-02 Thread Christian König

Am 01.11.23 um 09:13 schrieb Daniel Vetter:

On Wed, 1 Nov 2023 at 07:59, Dave Airlie  wrote:

Well, to make it clear once more: Signaling a dma_fence from the
destructor of a reference counted object is very problematic! This will
be rejected no matter if you do that in C or in Rust.

What we can do is to make it safe in the sense that you don't access
freed up memory by using the scheduler fences even more as wrapper
around the hardware fence as we do now. But this quite a change and
requires a bit more than just hacking around
drm_sched_fence_get_timeline_name().

I really think this needs to be documented if nothing else out of this thread.

Clearly nobody is going to get it right and hidden here in this
thread, this info isn't useful.

Can we have some sort of design document for the dma-fence/scheduler
interactions written and we can try and refine it with solutions on
the list, because I'm tired of people proposing things and NAK's
getting thrown around without anything to point people at.

The next NAK I see on the list will mean I block all patches from the
sender until they write a documentation patch, because seriously this
stuff is too hard for someone to just keep it in their head and expect
everyone else to understand from reading the code.

I very much like the idea that NAK replies are counted as "you've just
volunteered yourself for some documentation patches so that next time
around you can reply with a link to the docs instead of just a NAK".


Yeah, that sounds like a great idea to me as well :)

Especially when I can use it to convince managers that we need to have 
more work force on writing documentation.



I don't think we'll get out of these discussions otherwise, since
currently we have undocumented, but very tricky semantics of the
drm/sched codebase for ringbuffer scheduling which is extended to fw
scheduling in also very tricky ways, with not entirely clear impacts
on semantics of all the drm/sched things. And as a result we just pile
up enormous amounts of threads where I think the only thing assured is
that people talk past each another.


The scheduler is certainly the ugliest part, but it's unfortunately 
still only the tip of the iceberg.


I have seen at least halve a dozen approach in the last two years where 
people tried to signal a dma_fence from userspace or similar.


Fortunately it was mostly prototyping and I could jump in early enough 
to stop that, but basically this is a fight against windmills.


I was considering to change the dma_fence semantics so that 
dma_fence_signal() could only be called from the interrupt contexts of 
devices and then put a big fat WARN_ON(!in_interrupt()) in there.


It's a sledgehammer, but as far as I can see the only thing which might 
help. Opinions?


Thanks,
Christian.



Converting NAKs into doc patches should at least eventually get rid of
the worst confusions we're dealing with here.

Cheers, Sima




Re: [PATCH v2 0/2] fbdev/simplefb: Add missing simple-framebuffer features

2023-11-02 Thread Hans de Goede
Hi,

On 11/1/23 18:54, Hans de Goede wrote:
> Hi,
> 
> On 11/1/23 18:20, Thierry Reding wrote:
>> From: Thierry Reding 
>>
>> Hi,
>>
>> This contains two patches that bring simplefb up to feature parity with
>> simpledrm. The patches add support for the "memory-region" property that
>> provides an alternative to the "reg" property to describe the memory
>> used for the framebuffer and allow attaching the simple-framebuffer
>> device to one or more generic power domains to make sure they aren't
>> turned off during the boot process and take down the display
>> configuration.
>>
>> Changes in v2:
>> - remove unnecessary call to simplefb_detach_genpds() since that's
>>   already done automatically by devres
>> - fix crash if power-domains property is missing in DT
> 
> Thanks, the new version looks good to me:
> 
> Reviewed-by: Hans de Goede 
> 
> for the series.
> 
> Helge, will you pick these 2 up, or shall I push them to drm-misc-fixes?

I have pushed this to drm-misc-next now.

I now I said drm-misc-fixes at first, but on a second look
these really are not fixes, so getting them in mainline
will have to wait to the next merge-window.

Regards,

Hans





[PATCH 0/5] Some drm scheduler internal renames

2023-11-02 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

I found some of the naming a bit incosistent and unclear so just a small
attempt to clarify and tidy some of them. See what people think if my first
stab improves things or not.

Cc: Luben Tuikov 
Cc: Matthew Brost 

Tvrtko Ursulin (5):
  drm/sched: Rename drm_sched_get_cleanup_job to be more descriptive
  drm/sched: Move free worker re-queuing out of the if block
  drm/sched: Rename drm_sched_free_job_queue to be more descriptive
  drm/sched: Rename drm_sched_run_job_queue_if_ready and clarify
kerneldoc
  drm/sched: Drop suffix from drm_sched_wakeup_if_can_queue

 drivers/gpu/drm/scheduler/sched_entity.c |  4 +-
 drivers/gpu/drm/scheduler/sched_main.c   | 53 
 include/drm/gpu_scheduler.h  |  2 +-
 3 files changed, 29 insertions(+), 30 deletions(-)

-- 
2.39.2



[PATCH 3/5] drm/sched: Rename drm_sched_free_job_queue to be more descriptive

2023-11-02 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

The current name makes it sound like helper will free a queue, while what
it does is it enqueues the free job worker.

Rename it to drm_sched_run_free_queue to align with existing
drm_sched_run_job_queue.

Despite that creating an illusion there are two queues, while in reality
there is only one, at least it creates a consistent naming for the two
enqueuing helpers.

At the same time simplify the "if done" helper by dropping the suffix and
adding a double underscore prefix to the one which just enqueues.

Signed-off-by: Tvrtko Ursulin 
Cc: Luben Tuikov 
Cc: Matthew Brost 
---
 drivers/gpu/drm/scheduler/sched_main.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index e1658030613f..f9baca20b438 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -266,20 +266,20 @@ static void drm_sched_run_job_queue(struct 
drm_gpu_scheduler *sched)
 }
 
 /**
- * drm_sched_free_job_queue - enqueue free-job work
+ * __drm_sched_run_free_queue - enqueue free-job work
  * @sched: scheduler instance
  */
-static void drm_sched_free_job_queue(struct drm_gpu_scheduler *sched)
+static void __drm_sched_run_free_queue(struct drm_gpu_scheduler *sched)
 {
if (!READ_ONCE(sched->pause_submit))
queue_work(sched->submit_wq, &sched->work_free_job);
 }
 
 /**
- * drm_sched_free_job_queue_if_done - enqueue free-job work if ready
+ * drm_sched_run_free_queue - enqueue free-job work if ready
  * @sched: scheduler instance
  */
-static void drm_sched_free_job_queue_if_done(struct drm_gpu_scheduler *sched)
+static void drm_sched_run_free_queue(struct drm_gpu_scheduler *sched)
 {
struct drm_sched_job *job;
 
@@ -287,7 +287,7 @@ static void drm_sched_free_job_queue_if_done(struct 
drm_gpu_scheduler *sched)
job = list_first_entry_or_null(&sched->pending_list,
   struct drm_sched_job, list);
if (job && dma_fence_is_signaled(&job->s_fence->finished))
-   drm_sched_free_job_queue(sched);
+   __drm_sched_run_free_queue(sched);
spin_unlock(&sched->job_list_lock);
 }
 
@@ -310,7 +310,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job, 
int result)
dma_fence_get(&s_fence->finished);
drm_sched_fence_finished(s_fence, result);
dma_fence_put(&s_fence->finished);
-   drm_sched_free_job_queue(sched);
+   __drm_sched_run_free_queue(sched);
 }
 
 /**
@@ -1068,7 +1068,7 @@ static void drm_sched_free_job_work(struct work_struct *w)
if (job)
sched->ops->free_job(job);
 
-   drm_sched_free_job_queue_if_done(sched);
+   drm_sched_run_free_queue(sched);
drm_sched_run_job_queue_if_ready(sched);
 }
 
-- 
2.39.2



[PATCH 2/5] drm/sched: Move free worker re-queuing out of the if block

2023-11-02 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Whether or not there are more jobs to clean up does not depend on the
existance of the current job, given both drm_sched_get_finished_job and
drm_sched_free_job_queue_if_done take and drop the job list lock.
Therefore it is confusing to make it read like there is a dependency.

Signed-off-by: Tvrtko Ursulin 
Cc: Luben Tuikov 
Cc: Matthew Brost 
---
 drivers/gpu/drm/scheduler/sched_main.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index fb64b35451f5..e1658030613f 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -1065,12 +1065,11 @@ static void drm_sched_free_job_work(struct work_struct 
*w)
return;
 
job = drm_sched_get_finished_job(sched);
-   if (job) {
+   if (job)
sched->ops->free_job(job);
 
-   drm_sched_free_job_queue_if_done(sched);
-   drm_sched_run_job_queue_if_ready(sched);
-   }
+   drm_sched_free_job_queue_if_done(sched);
+   drm_sched_run_job_queue_if_ready(sched);
 }
 
 /**
-- 
2.39.2



[PATCH 1/5] drm/sched: Rename drm_sched_get_cleanup_job to be more descriptive

2023-11-02 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

"Get cleanup job" makes it sound like helper is returning a job which will
execute some cleanup, or something, while the kerneldoc itself accurately
says "fetch the next _finished_ job". So lets rename the helper to be self
documenting.

Signed-off-by: Tvrtko Ursulin 
Cc: Luben Tuikov 
Cc: Matthew Brost 
---
 drivers/gpu/drm/scheduler/sched_main.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index 98b2ad54fc70..fb64b35451f5 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -448,7 +448,7 @@ static void drm_sched_job_timedout(struct work_struct *work)
 
sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work);
 
-   /* Protects against concurrent deletion in drm_sched_get_cleanup_job */
+   /* Protects against concurrent deletion in drm_sched_get_finished_job */
spin_lock(&sched->job_list_lock);
job = list_first_entry_or_null(&sched->pending_list,
   struct drm_sched_job, list);
@@ -500,9 +500,9 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, struct 
drm_sched_job *bad)
 
/*
 * Reinsert back the bad job here - now it's safe as
-* drm_sched_get_cleanup_job cannot race against us and release the
+* drm_sched_get_finished_job cannot race against us and release the
 * bad job at this point - we parked (waited for) any in progress
-* (earlier) cleanups and drm_sched_get_cleanup_job will not be called
+* (earlier) cleanups and drm_sched_get_finished_job will not be called
 * now until the scheduler thread is unparked.
 */
if (bad && bad->sched == sched)
@@ -960,7 +960,7 @@ drm_sched_select_entity(struct drm_gpu_scheduler *sched)
 }
 
 /**
- * drm_sched_get_cleanup_job - fetch the next finished job to be destroyed
+ * drm_sched_get_finished_job - fetch the next finished job to be destroyed
  *
  * @sched: scheduler instance
  *
@@ -968,7 +968,7 @@ drm_sched_select_entity(struct drm_gpu_scheduler *sched)
  * ready for it to be destroyed.
  */
 static struct drm_sched_job *
-drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched)
+drm_sched_get_finished_job(struct drm_gpu_scheduler *sched)
 {
struct drm_sched_job *job, *next;
 
@@ -1059,14 +1059,14 @@ static void drm_sched_free_job_work(struct work_struct 
*w)
 {
struct drm_gpu_scheduler *sched =
container_of(w, struct drm_gpu_scheduler, work_free_job);
-   struct drm_sched_job *cleanup_job;
+   struct drm_sched_job *job;
 
if (READ_ONCE(sched->pause_submit))
return;
 
-   cleanup_job = drm_sched_get_cleanup_job(sched);
-   if (cleanup_job) {
-   sched->ops->free_job(cleanup_job);
+   job = drm_sched_get_finished_job(sched);
+   if (job) {
+   sched->ops->free_job(job);
 
drm_sched_free_job_queue_if_done(sched);
drm_sched_run_job_queue_if_ready(sched);
-- 
2.39.2



[PATCH 4/5] drm/sched: Rename drm_sched_run_job_queue_if_ready and clarify kerneldoc

2023-11-02 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

"If ready" is not immediately clear what it means - is the scheduler
ready or something else? Drop the suffix, clarify kerneldoc, and employ
the same naming scheme as in drm_sched_run_free_queue:

 - drm_sched_run_job_queue   - enqueues if there is something to enqueue
   *and* scheduler is ready (can queue)
 - __drm_sched_run_job_queue - low-level helper to simply queue the job

Signed-off-by: Tvrtko Ursulin 
Cc: Luben Tuikov 
Cc: Matthew Brost 
---
 drivers/gpu/drm/scheduler/sched_main.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index f9baca20b438..d5ddbce68fb7 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -256,10 +256,10 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
 }
 
 /**
- * drm_sched_run_job_queue - enqueue run-job work
+ * __drm_sched_run_job_queue - enqueue run-job work
  * @sched: scheduler instance
  */
-static void drm_sched_run_job_queue(struct drm_gpu_scheduler *sched)
+static void __drm_sched_run_job_queue(struct drm_gpu_scheduler *sched)
 {
if (!READ_ONCE(sched->pause_submit))
queue_work(sched->submit_wq, &sched->work_run_job);
@@ -928,7 +928,7 @@ static bool drm_sched_can_queue(struct drm_gpu_scheduler 
*sched)
 void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched)
 {
if (drm_sched_can_queue(sched))
-   drm_sched_run_job_queue(sched);
+   __drm_sched_run_job_queue(sched);
 }
 
 /**
@@ -1041,13 +1041,13 @@ drm_sched_pick_best(struct drm_gpu_scheduler 
**sched_list,
 EXPORT_SYMBOL(drm_sched_pick_best);
 
 /**
- * drm_sched_run_job_queue_if_ready - enqueue run-job work if ready
+ * drm_sched_run_job_queue - enqueue run-job work if there are ready entities
  * @sched: scheduler instance
  */
-static void drm_sched_run_job_queue_if_ready(struct drm_gpu_scheduler *sched)
+static void drm_sched_run_job_queue(struct drm_gpu_scheduler *sched)
 {
if (drm_sched_select_entity(sched))
-   drm_sched_run_job_queue(sched);
+   __drm_sched_run_job_queue(sched);
 }
 
 /**
@@ -1069,7 +1069,7 @@ static void drm_sched_free_job_work(struct work_struct *w)
sched->ops->free_job(job);
 
drm_sched_run_free_queue(sched);
-   drm_sched_run_job_queue_if_ready(sched);
+   drm_sched_run_job_queue(sched);
 }
 
 /**
@@ -1126,7 +1126,7 @@ static void drm_sched_run_job_work(struct work_struct *w)
}
 
wake_up(&sched->job_scheduled);
-   drm_sched_run_job_queue_if_ready(sched);
+   drm_sched_run_job_queue(sched);
 }
 
 /**
-- 
2.39.2



[PATCH 5/5] drm/sched: Drop suffix from drm_sched_wakeup_if_can_queue

2023-11-02 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Because a) helper is exported to other parts of the scheduler and
b) there isn't a plain drm_sched_wakeup to begin with, I think we can
drop the suffix and by doing so separate the intimiate knowledge
between the scheduler components a bit better.

Signed-off-by: Tvrtko Ursulin 
Cc: Luben Tuikov 
Cc: Matthew Brost 
---
 drivers/gpu/drm/scheduler/sched_entity.c | 4 ++--
 drivers/gpu/drm/scheduler/sched_main.c   | 4 ++--
 include/drm/gpu_scheduler.h  | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_entity.c 
b/drivers/gpu/drm/scheduler/sched_entity.c
index 409e4256f6e7..f1db63cc8198 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -370,7 +370,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
container_of(cb, struct drm_sched_entity, cb);
 
drm_sched_entity_clear_dep(f, cb);
-   drm_sched_wakeup_if_can_queue(entity->rq->sched);
+   drm_sched_wakeup(entity->rq->sched);
 }
 
 /**
@@ -602,7 +602,7 @@ void drm_sched_entity_push_job(struct drm_sched_job 
*sched_job)
if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
drm_sched_rq_update_fifo(entity, submit_ts);
 
-   drm_sched_wakeup_if_can_queue(entity->rq->sched);
+   drm_sched_wakeup(entity->rq->sched);
}
 }
 EXPORT_SYMBOL(drm_sched_entity_push_job);
diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index d5ddbce68fb7..27843e37d9b7 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -920,12 +920,12 @@ static bool drm_sched_can_queue(struct drm_gpu_scheduler 
*sched)
 }
 
 /**
- * drm_sched_wakeup_if_can_queue - Wake up the scheduler
+ * drm_sched_wakeup - Wake up the scheduler if it is ready to queue
  * @sched: scheduler instance
  *
  * Wake up the scheduler if we can queue jobs.
  */
-void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched)
+void drm_sched_wakeup(struct drm_gpu_scheduler *sched)
 {
if (drm_sched_can_queue(sched))
__drm_sched_run_job_queue(sched);
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index c1565694c0e9..43730f1ecbfd 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -558,7 +558,7 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity 
*entity,
 
 void drm_sched_tdr_queue_imm(struct drm_gpu_scheduler *sched);
 void drm_sched_job_cleanup(struct drm_sched_job *job);
-void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched);
+void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
 bool drm_sched_wqueue_ready(struct drm_gpu_scheduler *sched);
 void drm_sched_wqueue_stop(struct drm_gpu_scheduler *sched);
 void drm_sched_wqueue_start(struct drm_gpu_scheduler *sched);
-- 
2.39.2



Re: [accel/ivpu] Help -- Which Intel CPU processor can be used for iVPU driver?

2023-11-02 Thread Trigger Huang
Hi Jacek,

Thanks for the quick response.

Seems I need to wait for a while if I want to buy a  Meteor Lake based
platform because I got the following message from wiki(
*https://en.wikipedia.org/wiki/Meteor_Lake
)*

   *Meteor Lake is Intel's codename for the first-generation of
Intel Core Ultra mobile processors, to be released to the market on
December 14, 2023*

BTW, is it possible that NPU (formerly known as VPU) will be available on
some desktop CPUs in the future?

Thanks,
Trigger

On Thu, Nov 2, 2023 at 5:24 PM Jacek Lawrynowicz <
jacek.lawrynow...@linux.intel.com> wrote:

> Hi,
>
> You need a Meteor Lake based platform.
> Intel 14th gen desktop CPUs were supposed to be Meteor Lake but they ended
> up as Raptor Lake.
> NPU (formerly known as VPU) will be available in 14th gen mobile chips.
> I will update the Kconfig description.
>
> Regards,
> Jacek
>
> On 02.11.2023 07:59, Trigger Huang wrote:
> > Hello,
> >
> > I want to have a try for the iVPU driver but don't know which CPU
> platform
> > is suitable. Would you help?
> >
> > According to the description in linux/drivers/accel/ivpu/Kconfig, it says
> > that Choose this option if you have a system that has an *14*th
> generation
> > Intel CPU
> > But according to the Intel  I7 *14*700k spec (
> >
> https://www.intel.com/content/www/us/en/products/sku/236783/intel-core-i7-processor-14700k-33m-cache-up-to-5-60-ghz/specifications.html
> ),
> > there is
> > no description about Versatile Processing Unit.
> >
> > So which CPU should I choose?
> >
> > Thanks,
> > Trigger
> >
>


Re: [PATCH v8 3/5] drm/sched: Split free_job into own work item

2023-11-02 Thread Tvrtko Ursulin



On 31/10/2023 03:24, Matthew Brost wrote:

Rather than call free_job and run_job in same work item have a dedicated
work item for each. This aligns with the design and intended use of work
queues.

v2:
- Test for DMA_FENCE_FLAG_TIMESTAMP_BIT before setting
  timestamp in free_job() work item (Danilo)
v3:
   - Drop forward dec of drm_sched_select_entity (Boris)
   - Return in drm_sched_run_job_work if entity NULL (Boris)
v4:
   - Replace dequeue with peek and invert logic (Luben)
   - Wrap to 100 lines (Luben)
   - Update comments for *_queue / *_queue_if_ready functions (Luben)
v5:
   - Drop peek argument, blindly reinit idle (Luben)
   - s/drm_sched_free_job_queue_if_ready/drm_sched_free_job_queue_if_done 
(Luben)
   - Update work_run_job & work_free_job kernel doc (Luben)
v6:
   - Do not move drm_sched_select_entity in file (Luben)

Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/scheduler/sched_main.c | 146 +
  include/drm/gpu_scheduler.h|   4 +-
  2 files changed, 101 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index d1ae05bded15..3b1b2f8eafe8 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -265,6 +265,32 @@ static void drm_sched_run_job_queue(struct 
drm_gpu_scheduler *sched)
queue_work(sched->submit_wq, &sched->work_run_job);
  }
  
+/**

+ * drm_sched_free_job_queue - enqueue free-job work
+ * @sched: scheduler instance
+ */
+static void drm_sched_free_job_queue(struct drm_gpu_scheduler *sched)
+{
+   if (!READ_ONCE(sched->pause_submit))
+   queue_work(sched->submit_wq, &sched->work_free_job);
+}
+
+/**
+ * drm_sched_free_job_queue_if_done - enqueue free-job work if ready
+ * @sched: scheduler instance
+ */
+static void drm_sched_free_job_queue_if_done(struct drm_gpu_scheduler *sched)
+{
+   struct drm_sched_job *job;
+
+   spin_lock(&sched->job_list_lock);
+   job = list_first_entry_or_null(&sched->pending_list,
+  struct drm_sched_job, list);
+   if (job && dma_fence_is_signaled(&job->s_fence->finished))
+   drm_sched_free_job_queue(sched);
+   spin_unlock(&sched->job_list_lock);
+}
+
  /**
   * drm_sched_job_done - complete a job
   * @s_job: pointer to the job which is done
@@ -284,7 +310,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job, 
int result)
dma_fence_get(&s_fence->finished);
drm_sched_fence_finished(s_fence, result);
dma_fence_put(&s_fence->finished);
-   drm_sched_run_job_queue(sched);
+   drm_sched_free_job_queue(sched);
  }
  
  /**

@@ -943,8 +969,10 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched)
typeof(*next), list);
  
  		if (next) {

-   next->s_fence->scheduled.timestamp =
-   dma_fence_timestamp(&job->s_fence->finished);
+   if (test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT,
+&next->s_fence->scheduled.flags))
+   next->s_fence->scheduled.timestamp =
+   
dma_fence_timestamp(&job->s_fence->finished);
/* start TO timer for next job */
drm_sched_start_timeout(sched);
}
@@ -994,7 +1022,40 @@ drm_sched_pick_best(struct drm_gpu_scheduler **sched_list,
  EXPORT_SYMBOL(drm_sched_pick_best);
  
  /**

- * drm_sched_run_job_work - main scheduler thread
+ * drm_sched_run_job_queue_if_ready - enqueue run-job work if ready
+ * @sched: scheduler instance
+ */
+static void drm_sched_run_job_queue_if_ready(struct drm_gpu_scheduler *sched)
+{
+   if (drm_sched_select_entity(sched))
+   drm_sched_run_job_queue(sched);
+}
+
+/**
+ * drm_sched_free_job_work - worker to call free_job
+ *
+ * @w: free job work
+ */
+static void drm_sched_free_job_work(struct work_struct *w)
+{
+   struct drm_gpu_scheduler *sched =
+   container_of(w, struct drm_gpu_scheduler, work_free_job);
+   struct drm_sched_job *cleanup_job;
+
+   if (READ_ONCE(sched->pause_submit))
+   return;
+
+   cleanup_job = drm_sched_get_cleanup_job(sched);
+   if (cleanup_job) {
+   sched->ops->free_job(cleanup_job);
+
+   drm_sched_free_job_queue_if_done(sched);
+   drm_sched_run_job_queue_if_ready(sched);


Are finished jobs now disturbing the round robin selection?

Every time this cleans up a job we get:

drm_sched_run_job_queue_if_ready
 -> drm_sched_select_entity
 -> drm_sched_rq_select_entity_rr
 -> rq->current_entity bumped to next in list

So when the job run worker does:

entity = drm_sched_select_entity(sched);

It does not pick the same entity as before this patch? If so perhaps 
drm_sched_run_job_queu

Re: [PATCH 2/3] drm/scheduler: Fix UAF in drm_sched_fence_get_timeline_name

2023-11-02 Thread Lucas Stach
Am Donnerstag, dem 02.11.2023 um 11:48 +0100 schrieb Christian König:
[...]
> I was considering to change the dma_fence semantics so that 
> dma_fence_signal() could only be called from the interrupt contexts of 
> devices and then put a big fat WARN_ON(!in_interrupt()) in there.
> 
> It's a sledgehammer, but as far as I can see the only thing which might 
> help. Opinions?

That's not going to fly. As soon as you are dealing with device drivers
that use IRQ threads, either voluntarily or even involuntarily on RT
kernels, the dma_fence_signal will be from process context.

Regards,
Lucas


Re: [PATCH] drm/i915: Fix potential spectre vulnerability

2023-11-02 Thread Tvrtko Ursulin



On 02/11/2023 10:16, chentao wrote:

Fix smatch warning:
drivers/gpu/drm/i915/gem/i915_gem_context.c:847 set_proto_ctx_sseu()
warn: potential spectre issue 'pc->user_engines' [r] (local cap)

Signed-off-by: chentao 


I don't know if this is actually exploitable given the time deltas between the 
index is read from userspace and acted upon here, which is at least two ioctls 
apart. But I suppose no harm in fixing and for safety so we need to add:

Fixes: d4433c7600f7 ("drm/i915/gem: Use the proto-context to handle create 
parameters (v5)")
Cc:  # v5.15+


---
  drivers/gpu/drm/i915/gem/i915_gem_context.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 9a9ff84c90d7..b2fdfc7ca4de 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -843,7 +843,7 @@ static int set_proto_ctx_sseu(struct drm_i915_file_private 
*fpriv,
  
  		if (idx >= pc->num_user_engines)

return -EINVAL;
-


Just please refrain from random whitespace modifications like this blank line 
removal. If you resend without that you can add my r-b.

Regards,

Tvrtko


+   idx = array_index_nospec(idx, pc->num_user_engines);
pe = &pc->user_engines[idx];
  
  		/* Only render engine supports RPCS configuration. */


Re: [PATCH 2/2] drm/i915: Move for_each_engine* out of i915_drv.h

2023-11-02 Thread Jani Nikula
On Thu, 02 Nov 2023, Tvrtko Ursulin  wrote:
> From: Tvrtko Ursulin 
>
> Iterators operate on struct intel_gt so lets move it to intel_gt.h in
> order to make i915_drv.h less of a dumping ground for stuff.
>
> Signed-off-by: Tvrtko Ursulin 
> Suggested-by: Jani Nikula 

Reviewed-by: Jani Nikula 


> ---
>  drivers/gpu/drm/i915/gt/intel_engine_pm.h  |  1 +
>  drivers/gpu/drm/i915/gt/intel_gt.h | 14 ++
>  drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c |  2 +-
>  drivers/gpu/drm/i915/i915_drv.h| 14 --
>  drivers/gpu/drm/i915/selftests/intel_uncore.c  |  2 ++
>  5 files changed, 18 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.h 
> b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
> index d68675925b79..1d97c435a015 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_pm.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
> @@ -10,6 +10,7 @@
>  #include "i915_request.h"
>  #include "intel_engine_types.h"
>  #include "intel_wakeref.h"
> +#include "intel_gt.h"
>  #include "intel_gt_pm.h"
>  
>  static inline bool
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
> b/drivers/gpu/drm/i915/gt/intel_gt.h
> index 9ffdb05e231e..b0e453e27ea8 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.h
> @@ -171,6 +171,20 @@ void intel_gt_release_all(struct drm_i915_private *i915);
>(id__)++) \
>   for_each_if(((gt__) = (i915__)->gt[(id__)]))
>  
> +/* Simple iterator over all initialised engines */
> +#define for_each_engine(engine__, gt__, id__) \
> + for ((id__) = 0; \
> +  (id__) < I915_NUM_ENGINES; \
> +  (id__)++) \
> + for_each_if ((engine__) = (gt__)->engine[(id__)])
> +
> +/* Iterator over subset of engines selected by mask */
> +#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
> + for ((tmp__) = (mask__) & (gt__)->info.engine_mask; \
> +  (tmp__) ? \
> +  ((engine__) = (gt__)->engine[__mask_next_bit(tmp__)]), 1 : \
> +  0;)
> +
>  void intel_gt_info_print(const struct intel_gt_info *info,
>struct drm_printer *p);
>  
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c 
> b/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
> index 8f9b874fdc9c..3aa1d014c14d 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c
> @@ -6,8 +6,8 @@
>  
>  #include 
>  
> -#include "i915_drv.h" /* for_each_engine! */
>  #include "intel_engine.h"
> +#include "intel_gt.h"
>  #include "intel_gt_debugfs.h"
>  #include "intel_gt_engines_debugfs.h"
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index bf6ed434bb6b..f3be9033a93f 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -396,20 +396,6 @@ static inline struct intel_gt *to_gt(const struct 
> drm_i915_private *i915)
>   return i915->gt[0];
>  }
>  
> -/* Simple iterator over all initialised engines */
> -#define for_each_engine(engine__, gt__, id__) \
> - for ((id__) = 0; \
> -  (id__) < I915_NUM_ENGINES; \
> -  (id__)++) \
> - for_each_if ((engine__) = (gt__)->engine[(id__)])
> -
> -/* Iterator over subset of engines selected by mask */
> -#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
> - for ((tmp__) = (mask__) & (gt__)->info.engine_mask; \
> -  (tmp__) ? \
> -  ((engine__) = (gt__)->engine[__mask_next_bit(tmp__)]), 1 : \
> -  0;)
> -
>  #define rb_to_uabi_engine(rb) \
>   rb_entry_safe(rb, struct intel_engine_cs, uabi_node)
>  
> diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c 
> b/drivers/gpu/drm/i915/selftests/intel_uncore.c
> index 03ea75cd84dd..4f98aa8a861e 100644
> --- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
> @@ -24,6 +24,8 @@
>  
>  #include "../i915_selftest.h"
>  
> +#include "gt/intel_gt.h"
> +
>  static int intel_fw_table_check(const struct intel_forcewake_range *ranges,
>   unsigned int num_ranges,
>   bool is_watertight)

-- 
Jani Nikula, Intel


Re: [PATCH v2 6/7] drm/i915/dsi: Replace poking of CHV GPIOs behind the driver's back

2023-11-02 Thread Andy Shevchenko
On Wed, Nov 01, 2023 at 12:01:31PM +0100, Hans de Goede wrote:
> On 11/1/23 11:20, Hans de Goede wrote:

...

> Attached is this patch, this should probably be one of
> the first patches in the v3 submission.

Thanks, noted!

> Note that if you go with Ville's suggestion to preparse
> the MIPI sequences, things will change significantly
> and then the attached patch will likely be unnecessary.

I don't think so I'm for that. My task is to get rid of the poking registers
of the GPIO IPs in the kernel when driver has no clue about them.

That's why I want to do minimum in that sense with less possible invasion
into existing flow.

-- 
With Best Regards,
Andy Shevchenko




Re: Blank screen on boot of Linux 6.5 and later on Lenovo ThinkPad L570

2023-11-02 Thread Huacai Chen
Hi, Jaak,

On Wed, Nov 1, 2023 at 7:52 PM Jaak Ristioja  wrote:
>
> On 31.10.23 14:17, Huacai Chen wrote:
> > Hi, Jaak and Evan,
> >
> > On Sun, Oct 29, 2023 at 9:42 AM Huacai Chen  wrote:
> >>
> >> On Sat, Oct 28, 2023 at 7:06 PM Jaak Ristioja  wrote:
> >>>
> >>> On 26.10.23 03:58, Huacai Chen wrote:
>  Hi, Jaak,
> 
>  On Thu, Oct 26, 2023 at 2:49 AM Jaak Ristioja  wrote:
> >
> > On 25.10.23 16:23, Huacai Chen wrote:
> >> On Wed, Oct 25, 2023 at 6:08 PM Thorsten Leemhuis
> >>  wrote:
> >>>
> >>> Javier, Dave, Sima,
> >>>
> >>> On 23.10.23 00:54, Evan Preston wrote:
>  On 2023-10-20 Fri 05:48pm, Huacai Chen wrote:
> > On Fri, Oct 20, 2023 at 5:35 PM Linux regression tracking (Thorsten
> > Leemhuis)  wrote:
> >> On 09.10.23 10:54, Huacai Chen wrote:
> >>> On Mon, Oct 9, 2023 at 4:45 PM Bagas Sanjaya 
> >>>  wrote:
>  On Mon, Oct 09, 2023 at 09:27:02AM +0800, Huacai Chen wrote:
> > On Tue, Sep 26, 2023 at 10:31 PM Huacai Chen 
> >  wrote:
> >> On Tue, Sep 26, 2023 at 7:15 PM Linux regression tracking 
> >> (Thorsten
> >> Leemhuis)  wrote:
> >>> On 13.09.23 14:02, Jaak Ristioja wrote:
> 
>  Upgrading to Linux 6.5 on a Lenovo ThinkPad L570 (Integrated 
>  Intel HD
>  Graphics 620 (rev 02), Intel(R) Core(TM) i7-7500U) results 
>  in a blank
>  screen after boot until the display manager starts... if it 
>  does start
>  at all. Using the nomodeset kernel parameter seems to be a 
>  workaround.
> 
>  I've bisected this to commit 
>  60aebc9559492cea6a9625f514a8041717e3a2e4
>  ("drivers/firmware: Move sysfb_init() from device_initcall to
>  subsys_initcall_sync").
> >>>
> > As confirmed by Jaak, disabling DRM_SIMPLEDRM makes things work 
> > fine
> > again. So I guess the reason:
> >>
> >> Well, this to me still looks a lot (please correct me if I'm 
> >> wrong) like
> >> regression that should be fixed, as DRM_SIMPLEDRM was enabled 
> >> beforehand
> >> if I understood things correctly. Or is there a proper fix for this
> >> already in the works and I just missed this? Or is there some good
> >> reason why this won't/can't be fixed?
> >
> > DRM_SIMPLEDRM was enabled but it didn't work at all because there 
> > was
> > no corresponding platform device. Now DRM_SIMPLEDRM works but it 
> > has a
> > blank screen. Of course it is valuable to investigate further about
> > DRM_SIMPLEDRM on Jaak's machine, but that needs Jaak's effort 
> > because
> > I don't have a same machine.
> >>>
> >>> Side note: Huacai, have you tried working with Jaak to get down to the
> >>> real problem? Evan, might you be able to help out here?
> >> No, Jaak has no response after he 'fixed' his problem by disabling 
> >> SIMPLEDRM.
> >>
> >
> > I'm sorry, what was it exactly you want me to do? Please be mindful that
> > I'm not familiar with the internals of the Linux kernel and DRI, and it
> > might sometimes take weeks before I have time to work and respond on 
> > this.
>  It doesn't matter. I hope you can do some experiments to investigate
>  deeper. The first experiment you can do is enabling SIMPLEFB (i.e.
>  CONFIG_FB_SIMPLE) instead of SIMPLEDRM (CONFIG_DRM_SIMPLEDRM) to see
>  whether there is also a blank screen. If no blank screen, that
>  probably means SIMPLEDRM has a bug, if still blank screen, that means
>  the firmware may pass wrong screen information.
> >>>
> >>> Testing with 6.5.9 I get a blank screen with CONFIG_DRM_SIMPLEDRM=y and
> >>> get no blank screen with CONFIG_FB_SIMPLE=y and CONFIG_DRM_SIMPLEDRM 
> >>> unset.
> >> CONFIG_FB_SIMPLE and  CONFIG_DRM_SIMPLEDRM use the same device created
> >> by sysfb_init(). Since FB_SIMPLE works fine, I think the real problem
> >> is that DRM_SIMPLEDRM has a bug. The next step is to enable
> >> CONFIG_DRM_SIMPLEDRM and trace its initialization. In detail, adding
> >> some printk() in simpledrm_probe() and its sub-routines to see where
> >> the driver fails. The output of these printk() can be seen by the
> >> 'dmesg' command after boot.
> > I need your help. I tried with my laptop (ThinkPad E490, Intel Core
> > i3-8145U, UHD Graphics 620) but I can't reproduce your problem. So
> > please patch your 6.5.x kernel with this temporary patch [1], then
> > build a "bad kernel" with SIMPLEDRM enabled. And after booting your
> > machine with this "bad kernel", please give me the dmesg output. Thank
> > you very much.
> >
> > [1] http://ddns.miaomiao

Re: [PATCH 2/3] drm/scheduler: Fix UAF in drm_sched_fence_get_timeline_name

2023-11-02 Thread Christian König

Am 02.11.23 um 12:19 schrieb Lucas Stach:

Am Donnerstag, dem 02.11.2023 um 11:48 +0100 schrieb Christian König:
[...]

I was considering to change the dma_fence semantics so that
dma_fence_signal() could only be called from the interrupt contexts of
devices and then put a big fat WARN_ON(!in_interrupt()) in there.

It's a sledgehammer, but as far as I can see the only thing which might
help. Opinions?

That's not going to fly. As soon as you are dealing with device drivers
that use IRQ threads, either voluntarily or even involuntarily on RT
kernels, the dma_fence_signal will be from process context.


Ah shit, yeah of course. We use IRQ threads in amdgpu for the second 
interrupt ring as well.


Ok, nail that coffin. Any other ideas how we could enforce this?

Thanks,
Christian.



Regards,
Lucas




Re: [RFC PATCH v4 1/7] drm/panel: nv3052c: Document known register names

2023-11-02 Thread Linus Walleij
On Mon, Oct 30, 2023 at 8:24 AM John Watts  wrote:

> Many of these registers have a known name in the public datasheet.
> Document them as comments for reference.
>
> Signed-off-by: John Watts 
> Reviewed-by: Jessica Zhang 

This makes things better so:
Reviewed-by: Linus Walleij 

Yours,
Linus Walleij


Re: [RFC PATCH v4 4/7] drm/panel: nv3052c: Add Fascontek FS035VG158 LCD display

2023-11-02 Thread Linus Walleij
On Mon, Oct 30, 2023 at 8:24 AM John Watts  wrote:

> This display is extremely similar to the LTK035C5444T, but still has
> some minor variations in panel initialization.
>
> Signed-off-by: John Watts 
> Reviewed-by: Jessica Zhang 

Reviewed-by: Linus Walleij 

Yours,
Linus Walleij


Re: [RFC 02/11] drm: move lru_lock from ttm_device to drm_device

2023-11-02 Thread Christian König

Am 02.11.23 um 05:32 schrieb Oak Zeng:

In the coming patches, we will share the lru list b/t
ttm bo based memory allocator and hmm/svm based memory
allocator. Thus lru_lock (which is used mainly to protect
the lru list) is moved from struct ttm_device to struct
drm_device, so this lock can be shared b/t those two
memory allocators.

To minimize code change, struct ttm_device still hold
a weak reference of lru_lock, so ttm layer can still
reference to this lock easily.


I would rather like to see drm_device to become the base class of 
ttm_device.


Similar to how drm_gem_object is the base class of ttm_buffer_object.

That is probably a bit more work, but would also eliminate some of the 
duplicate house keeping we currently have (e.g. bdev pointer in 
ttm_buffer_object etc...).


Moving then stuff from the ttm_device into the drm_device becomes trivial.

Regards,
Christian.



Signed-off-by: Oak Zeng 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c   |  4 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c |  4 +-
  drivers/gpu/drm/drm_drv.c|  1 +
  drivers/gpu/drm/i915/gem/i915_gem_ttm.c  |  4 +-
  drivers/gpu/drm/ttm/ttm_bo.c | 40 +--
  drivers/gpu/drm/ttm/ttm_device.c | 18 -
  drivers/gpu/drm/ttm/ttm_resource.c   | 42 ++--
  drivers/gpu/drm/xe/xe_bo.c   |  4 +-
  drivers/gpu/drm/xe/xe_exec.c |  4 +-
  drivers/gpu/drm/xe/xe_vm.c   |  4 +-
  include/drm/drm_device.h |  5 +++
  include/drm/ttm/ttm_bo.h |  4 +-
  include/drm/ttm/ttm_device.h |  4 +-
  13 files changed, 72 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index f5daadcec865..747bcad86d5d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -368,9 +368,9 @@ int amdgpu_vm_lock_pd(struct amdgpu_vm *vm, struct drm_exec 
*exec,
  void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev,
struct amdgpu_vm *vm)
  {
-   spin_lock(&adev->mman.bdev.lru_lock);
+   spin_lock(adev->mman.bdev.lru_lock);
ttm_lru_bulk_move_tail(&vm->lru_bulk_move);
-   spin_unlock(&adev->mman.bdev.lru_lock);
+   spin_unlock(adev->mman.bdev.lru_lock);
  }
  
  /* Create scheduler entities for page table updates */

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index c7085a747b03..b83e1741905e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -290,9 +290,9 @@ static void amdgpu_vram_mgr_do_reserve(struct 
ttm_resource_manager *man)
  
  		vis_usage = amdgpu_vram_mgr_vis_size(adev, block);

atomic64_add(vis_usage, &mgr->vis_usage);
-   spin_lock(&man->bdev->lru_lock);
+   spin_lock(man->bdev->lru_lock);
man->usage += rsv->size;
-   spin_unlock(&man->bdev->lru_lock);
+   spin_unlock(man->bdev->lru_lock);
list_move(&rsv->blocks, &mgr->reserved_pages);
}
  }
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 3eda026ffac6..1943c38815aa 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -623,6 +623,7 @@ static int drm_dev_init(struct drm_device *dev,
  
  	INIT_LIST_HEAD(&dev->managed.resources);

spin_lock_init(&dev->managed.lock);
+   spin_lock_init(&dev->lru_lock);
  
  	/* no per-device feature limits by default */

dev->driver_features = ~0u;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index 9227f8146a58..c46f54f83f54 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -984,7 +984,7 @@ void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj)
/*
 * Put on the correct LRU list depending on the MADV status
 */
-   spin_lock(&bo->bdev->lru_lock);
+   spin_lock(bo->bdev->lru_lock);
if (shrinkable) {
/* Try to keep shmem_tt from being considered for shrinking. */
bo->priority = TTM_MAX_BO_PRIORITY - 1;
@@ -1013,7 +1013,7 @@ void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj)
}
  
  	ttm_bo_move_to_lru_tail(bo);

-   spin_unlock(&bo->bdev->lru_lock);
+   spin_unlock(bo->bdev->lru_lock);
  }
  
  /*

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index e58b7e249816..26e0555bad0c 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -68,7 +68,7 @@ static void ttm_bo_mem_space_debug(struct ttm_buffer_object 
*bo,
   * @bo: The buffer object.
   *
   * Move this BO to the tail of all lru lists used to lookup and reserve an
- * object. This function must be called with struct ttm

Re: [RFC PATCH v4 2/7] drm/panel: nv3052c: Add SPI device IDs

2023-11-02 Thread Linus Walleij
On Mon, Oct 30, 2023 at 8:24 AM John Watts  wrote:

> SPI drivers needs their own list of compatible device IDs in order
> for automatic module loading to work. Add those for this driver.
>
> Signed-off-by: John Watts 
> Reviewed-by: Jessica Zhang 

Reviewed-by: Linus Walleij 

Yours,
Linus Walleij


[PULL] drm-misc-fixes

2023-11-02 Thread Thomas Zimmermann
Hi,

this is the PR for drm-misc-fixes.

Best regards
Thomas

drm-misc-fixes-2023-11-02:
Short summary of fixes pull:

syncobj:
- Fix waiting for DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE

vc4:
- Fix UAF in mock helpers
The following changes since commit b132ac51d7a50c37683be56c96ff64f8c887930f:

  accel/ivpu/37xx: Fix missing VPUIP interrupts (2023-10-26 07:43:28 +0200)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2023-11-02

for you to fetch changes up to 101c9f637efa1655f55876644d4439e552267527:

  drm/syncobj: fix DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (2023-10-26 21:20:25 
+0200)


Short summary of fixes pull:

syncobj:
- Fix waiting for DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE

vc4:
- Fix UAF in mock helpers


Erik Kurzinger (1):
  drm/syncobj: fix DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE

Maxime Ripard (1):
  drm/vc4: tests: Fix UAF in the mock helpers

 drivers/gpu/drm/drm_syncobj.c   | 3 ++-
 drivers/gpu/drm/vc4/tests/vc4_mock_crtc.c   | 2 +-
 drivers/gpu/drm/vc4/tests/vc4_mock_output.c | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

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


[PATCH] drm/panel: starry-2081101qfh032011-53g: Fine tune the panel power sequence

2023-11-02 Thread xiazhengqiao
For "starry, 2081101qfh032011-53g" this panel, it is stipulated in the
panel spec that MIPI needs to keep the LP11 state before the
lcm_reset pin is pulled high.

Signed-off-by: xiazhengqiao 
---
 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c 
b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 4f370bc6dca8..4ed8c2e28d37 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -1765,6 +1765,7 @@ static const struct panel_desc starry_qfh032011_53g_desc 
= {
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
  MIPI_DSI_MODE_LPM,
.init_cmds = starry_qfh032011_53g_init_cmd,
+   .lp11_before_reset = true,
 };
 
 static const struct drm_display_mode starry_himax83102_j02_default_mode = {
-- 
2.17.1



[PATCH v6 2/7] drm/client: Export drm_client_dev_unregister()

2023-11-02 Thread Thomas Zimmermann
Export drm_client_dev_unregister() for use by the i915 driver. The
driver does not use drm_dev_unregister(), so it has to clean up the
in-kernel DRM clients by itself.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_client.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 9403b3f576f7b..3d4f8b77d0789 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -172,6 +172,18 @@ void drm_client_release(struct drm_client_dev *client)
 }
 EXPORT_SYMBOL(drm_client_release);
 
+/**
+ * drm_client_dev_unregister - Unregister clients
+ * @dev: DRM device
+ *
+ * This function releases all clients by calling each client's
+ * &drm_client_funcs.unregister callback. The callback function
+ * is responsibe for releaseing all resources including the client
+ * itself.
+ *
+ * The helper drm_dev_unregister() calls this function. Drivers
+ * that use it don't need to call this function themselves.
+ */
 void drm_client_dev_unregister(struct drm_device *dev)
 {
struct drm_client_dev *client, *tmp;
@@ -191,6 +203,7 @@ void drm_client_dev_unregister(struct drm_device *dev)
}
mutex_unlock(&dev->clientlist_mutex);
 }
+EXPORT_SYMBOL(drm_client_dev_unregister);
 
 /**
  * drm_client_dev_hotplug - Send hotplug event to clients
-- 
2.42.0



[PATCH v6 0/7] drm/i915: Convert fbdev to DRM client

2023-11-02 Thread Thomas Zimmermann
Convert i915's fbdev code to struct drm_client. Replaces the current
ad-hoc integration. The conversion includes a number of cleanups. The
patchset also enables unloading of driver modules with in-kernel DRM
clients; a feature required by i915.

As with the other drivers' fbdev emulation, fbdev in i915 is now
an in-kernel DRM client that runs after the DRM device has been
registered. This allows to remove the asynchronous initialization.

i915 is the last driver with an fbdev emulation that is not build
upon struct drm_client. Once reviewed, the patches would ideally go
into drm-misc-next, so that the old fbdev helper code can be removed.
We can also attempt to add additional in-kernel clients. A DRM-based
dmesg log or a bootsplash are commonly mentioned. DRM can then switch
easily among the existing clients if/when required.

v6:
* reorder patches to fix build (Jouni)
* remove unnecessary handling of non-atomic commits (Jouni, Ville)
* return errors from callbacks (Jouni)
* various minor fixes
v5:
* style fixes (checkpatch)
v4:

v3:
* support module unloading (Jani, CI bot)
* as before, silently ignore devices without displays (CI  bot)
v2:
* fix error handling (Jani)
* fix non-fbdev builds
* various minor fixes and cleanups

Thomas Zimmermann (7):
  drm/client: Do not acquire module reference
  drm/client: Export drm_client_dev_unregister()
  drm/i915: Unregister in-kernel clients
  drm/i915: Move fbdev functions
  drm/i915: Initialize fbdev DRM client with callback functions
  drm/i915: Implement fbdev client callbacks
  drm/i915: Implement fbdev emulation as in-kernel client

 drivers/gpu/drm/drm_client.c  |  25 +-
 drivers/gpu/drm/i915/display/intel_display.c  |   1 -
 .../drm/i915/display/intel_display_driver.c   |  19 --
 drivers/gpu/drm/i915/display/intel_fbdev.c| 265 ++
 drivers/gpu/drm/i915/display/intel_fbdev.h|  29 +-
 drivers/gpu/drm/i915/i915_driver.c|  27 +-
 6 files changed, 167 insertions(+), 199 deletions(-)


base-commit: b7816c393496dc4497c1327310821407f7171d8b
-- 
2.42.0



[PATCH v6 3/7] drm/i915: Unregister in-kernel clients

2023-11-02 Thread Thomas Zimmermann
Unregister all in-kernel clients before unloading the i915 driver. For
other drivers, drm_dev_unregister() does this automatically. As i915
does not use this helper, it has to perform the call by itself.

Note that there are currently no in-kernel clients in i915. The patch
prepares the driver for a related update of its fbdev support.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/i915/i915_driver.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_driver.c 
b/drivers/gpu/drm/i915/i915_driver.c
index 80e85cadb9a26..f7b56dcc96a16 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -41,6 +41,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -857,6 +858,8 @@ void i915_driver_remove(struct drm_i915_private *i915)
 {
intel_wakeref_t wakeref;
 
+   drm_client_dev_unregister(&i915->drm);
+
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
 
i915_driver_unregister(i915);
-- 
2.42.0



[PATCH v6 1/7] drm/client: Do not acquire module reference

2023-11-02 Thread Thomas Zimmermann
Do not acquire a reference on the module that provides a client's
callback functions in drm_client_init(). The additional reference
prevents the user from unloading the callback functions' module and
thus creating dangling pointers.

This is only necessary if there is no direct dependency between the
caller of drm_client_init() and the provider of the callbacks in
struct drm_client_funcs. If this case ever existed, it has been
removed from the DRM code. Callers of drm_client_init() also provide
the callback implementation. The lifetime of the clients is tied to
the dependency chain's outer-most module, which is the hardware's
DRM driver. Before client helpers could be unloaded, the driver module
would have to be unloaded, which also unregisters all clients.

Driver modules that set up DRM clients can now be unloaded.

Signed-off-by: Thomas Zimmermann 
Acked-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/drm_client.c | 12 +---
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index c3027115d0552..9403b3f576f7b 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -5,7 +5,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -84,16 +83,13 @@ int drm_client_init(struct drm_device *dev, struct 
drm_client_dev *client,
if (!drm_core_check_feature(dev, DRIVER_MODESET) || 
!dev->driver->dumb_create)
return -EOPNOTSUPP;
 
-   if (funcs && !try_module_get(funcs->owner))
-   return -ENODEV;
-
client->dev = dev;
client->name = name;
client->funcs = funcs;
 
ret = drm_client_modeset_create(client);
if (ret)
-   goto err_put_module;
+   return ret;
 
ret = drm_client_open(client);
if (ret)
@@ -105,10 +101,6 @@ int drm_client_init(struct drm_device *dev, struct 
drm_client_dev *client,
 
 err_free:
drm_client_modeset_free(client);
-err_put_module:
-   if (funcs)
-   module_put(funcs->owner);
-
return ret;
 }
 EXPORT_SYMBOL(drm_client_init);
@@ -177,8 +169,6 @@ void drm_client_release(struct drm_client_dev *client)
drm_client_modeset_free(client);
drm_client_close(client);
drm_dev_put(dev);
-   if (client->funcs)
-   module_put(client->funcs->owner);
 }
 EXPORT_SYMBOL(drm_client_release);
 
-- 
2.42.0



[PATCH v6 6/7] drm/i915: Implement fbdev client callbacks

2023-11-02 Thread Thomas Zimmermann
Move code from ad-hoc fbdev callbacks into DRM client functions
and remove the old callbacks. The functions instruct the client
to poll for changed output or restore the display.

The DRM core calls both, the old callbacks and the new client
helpers, from the same places. The new functions perform the same
operation as before, so there's no change in functionality.

v6:
* return errors from client callbacks (Jouni)

Signed-off-by: Thomas Zimmermann 
---
 .../drm/i915/display/intel_display_driver.c   |  1 -
 drivers/gpu/drm/i915/display/intel_fbdev.c| 33 ++-
 drivers/gpu/drm/i915/display/intel_fbdev.h|  9 -
 drivers/gpu/drm/i915/i915_driver.c| 22 -
 4 files changed, 25 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c 
b/drivers/gpu/drm/i915/display/intel_display_driver.c
index 44b59ac301e69..ffdcddd1943e0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -96,7 +96,6 @@ void intel_display_driver_init_hw(struct drm_i915_private 
*i915)
 static const struct drm_mode_config_funcs intel_mode_funcs = {
.fb_create = intel_user_framebuffer_create,
.get_format_info = intel_fb_get_format_info,
-   .output_poll_changed = intel_fbdev_output_poll_changed,
.mode_valid = intel_mode_valid,
.atomic_check = intel_atomic_check,
.atomic_commit = intel_atomic_commit,
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 88c554ea7bb19..2837791613608 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -638,13 +638,13 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int 
state, bool synchronous
intel_fbdev_hpd_set_suspend(dev_priv, state);
 }
 
-void intel_fbdev_output_poll_changed(struct drm_device *dev)
+static int intel_fbdev_output_poll_changed(struct drm_device *dev)
 {
struct intel_fbdev *ifbdev = to_i915(dev)->display.fbdev.fbdev;
bool send_hpd;
 
if (!ifbdev)
-   return;
+   return -EINVAL;
 
intel_fbdev_sync(ifbdev);
 
@@ -655,21 +655,29 @@ void intel_fbdev_output_poll_changed(struct drm_device 
*dev)
 
if (send_hpd && (ifbdev->vma || ifbdev->helper.deferred_setup))
drm_fb_helper_hotplug_event(&ifbdev->helper);
+
+   return 0;
 }
 
-void intel_fbdev_restore_mode(struct drm_i915_private *dev_priv)
+static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv)
 {
struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;
+   int ret;
 
if (!ifbdev)
-   return;
+   return -EINVAL;
 
intel_fbdev_sync(ifbdev);
if (!ifbdev->vma)
-   return;
+   return -ENOMEM;
 
-   if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper) == 0)
-   intel_fbdev_invalidate(ifbdev);
+   ret = drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper);
+   if (ret)
+   return ret;
+
+   intel_fbdev_invalidate(ifbdev);
+
+   return 0;
 }
 
 /*
@@ -681,12 +689,21 @@ static void intel_fbdev_client_unregister(struct 
drm_client_dev *client)
 
 static int intel_fbdev_client_restore(struct drm_client_dev *client)
 {
+   struct drm_i915_private *dev_priv = to_i915(client->dev);
+   int ret;
+
+   ret = intel_fbdev_restore_mode(dev_priv);
+   if (ret)
+   return ret;
+
+   vga_switcheroo_process_delayed_switch();
+
return 0;
 }
 
 static int intel_fbdev_client_hotplug(struct drm_client_dev *client)
 {
-   return 0;
+   return intel_fbdev_output_poll_changed(client->dev);
 }
 
 static const struct drm_client_funcs intel_fbdev_client_funcs = {
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h 
b/drivers/gpu/drm/i915/display/intel_fbdev.h
index 04fd523a50232..8c953f102ba22 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.h
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.h
@@ -19,8 +19,6 @@ void intel_fbdev_initial_config_async(struct drm_i915_private 
*dev_priv);
 void intel_fbdev_unregister(struct drm_i915_private *dev_priv);
 void intel_fbdev_fini(struct drm_i915_private *dev_priv);
 void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool 
synchronous);
-void intel_fbdev_output_poll_changed(struct drm_device *dev);
-void intel_fbdev_restore_mode(struct drm_i915_private *dev_priv);
 struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev);
 #else
 static inline int intel_fbdev_init(struct drm_device *dev)
@@ -44,13 +42,6 @@ static inline void intel_fbdev_set_suspend(struct drm_device 
*dev, int state, bo
 {
 }
 
-static inline void intel_fbdev_output_poll_changed(struct drm_device *dev)
-{
-}
-
-static inline void intel_fbdev_restore_mode(struct drm_i915_private *i915)
-{
-}
 static inline struct in

[PATCH v6 4/7] drm/i915: Move fbdev functions

2023-11-02 Thread Thomas Zimmermann
Move functions within intel_fbdev.c to simplify later updates. Minor
style fixes to make checkpatch happy, but no functional changes.

v5:
* style fixes (checkpatch)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Jouni Högander 
---
 drivers/gpu/drm/i915/display/intel_fbdev.c | 154 ++---
 1 file changed, 77 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 31d0d695d5671..2695c65b55ddc 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -545,58 +545,6 @@ static void intel_fbdev_suspend_worker(struct work_struct 
*work)
true);
 }
 
-int intel_fbdev_init(struct drm_device *dev)
-{
-   struct drm_i915_private *dev_priv = to_i915(dev);
-   struct intel_fbdev *ifbdev;
-   int ret;
-
-   if (drm_WARN_ON(dev, !HAS_DISPLAY(dev_priv)))
-   return -ENODEV;
-
-   ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
-   if (ifbdev == NULL)
-   return -ENOMEM;
-
-   mutex_init(&ifbdev->hpd_lock);
-   drm_fb_helper_prepare(dev, &ifbdev->helper, 32, &intel_fb_helper_funcs);
-
-   if (intel_fbdev_init_bios(dev, ifbdev))
-   ifbdev->helper.preferred_bpp = ifbdev->preferred_bpp;
-   else
-   ifbdev->preferred_bpp = ifbdev->helper.preferred_bpp;
-
-   ret = drm_fb_helper_init(dev, &ifbdev->helper);
-   if (ret) {
-   kfree(ifbdev);
-   return ret;
-   }
-
-   dev_priv->display.fbdev.fbdev = ifbdev;
-   INIT_WORK(&dev_priv->display.fbdev.suspend_work, 
intel_fbdev_suspend_worker);
-
-   return 0;
-}
-
-static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
-{
-   struct intel_fbdev *ifbdev = data;
-
-   /* Due to peculiar init order wrt to hpd handling this is separate. */
-   if (drm_fb_helper_initial_config(&ifbdev->helper))
-   intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
-}
-
-void intel_fbdev_initial_config_async(struct drm_i915_private *dev_priv)
-{
-   struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;
-
-   if (!ifbdev)
-   return;
-
-   ifbdev->cookie = async_schedule(intel_fbdev_initial_config, ifbdev);
-}
-
 static void intel_fbdev_sync(struct intel_fbdev *ifbdev)
 {
if (!ifbdev->cookie)
@@ -607,31 +555,6 @@ static void intel_fbdev_sync(struct intel_fbdev *ifbdev)
ifbdev->cookie = 0;
 }
 
-void intel_fbdev_unregister(struct drm_i915_private *dev_priv)
-{
-   struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;
-
-   if (!ifbdev)
-   return;
-
-   intel_fbdev_set_suspend(&dev_priv->drm, FBINFO_STATE_SUSPENDED, true);
-
-   if (!current_is_async())
-   intel_fbdev_sync(ifbdev);
-
-   drm_fb_helper_unregister_info(&ifbdev->helper);
-}
-
-void intel_fbdev_fini(struct drm_i915_private *dev_priv)
-{
-   struct intel_fbdev *ifbdev = 
fetch_and_zero(&dev_priv->display.fbdev.fbdev);
-
-   if (!ifbdev)
-   return;
-
-   intel_fbdev_destroy(ifbdev);
-}
-
 /* Suspends/resumes fbdev processing of incoming HPD events. When resuming HPD
  * processing, fbdev will perform a full connector reprobe if a hotplug event
  * was received while HPD was suspended.
@@ -748,6 +671,83 @@ void intel_fbdev_restore_mode(struct drm_i915_private 
*dev_priv)
intel_fbdev_invalidate(ifbdev);
 }
 
+int intel_fbdev_init(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   struct intel_fbdev *ifbdev;
+   int ret;
+
+   if (drm_WARN_ON(dev, !HAS_DISPLAY(dev_priv)))
+   return -ENODEV;
+
+   ifbdev = kzalloc(sizeof(*ifbdev), GFP_KERNEL);
+   if (!ifbdev)
+   return -ENOMEM;
+
+   mutex_init(&ifbdev->hpd_lock);
+   drm_fb_helper_prepare(dev, &ifbdev->helper, 32, &intel_fb_helper_funcs);
+
+   if (intel_fbdev_init_bios(dev, ifbdev))
+   ifbdev->helper.preferred_bpp = ifbdev->preferred_bpp;
+   else
+   ifbdev->preferred_bpp = ifbdev->helper.preferred_bpp;
+
+   ret = drm_fb_helper_init(dev, &ifbdev->helper);
+   if (ret) {
+   kfree(ifbdev);
+   return ret;
+   }
+
+   dev_priv->display.fbdev.fbdev = ifbdev;
+   INIT_WORK(&dev_priv->display.fbdev.suspend_work, 
intel_fbdev_suspend_worker);
+
+   return 0;
+}
+
+static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
+{
+   struct intel_fbdev *ifbdev = data;
+
+   /* Due to peculiar init order wrt to hpd handling this is separate. */
+   if (drm_fb_helper_initial_config(&ifbdev->helper))
+   intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
+}
+
+void intel_fbdev_initial_config_async(struct drm_i915_private *dev_priv)
+{
+   struct intel_fbdev *ifbdev = dev_priv->display

[PATCH v6 7/7] drm/i915: Implement fbdev emulation as in-kernel client

2023-11-02 Thread Thomas Zimmermann
Replace all code that initializes or releases fbdev emulation
throughout the driver. Instead initialize the fbdev client by a
single call to intel_fbdev_setup() after i915 has registered its
DRM device. Just like similar code in other drivers, i915 fbdev
emulation now acts like a regular DRM client.

The fbdev client setup consists of the initial preparation and the
hot-plugging of the display. The latter creates the fbdev device
and sets up the fbdev framebuffer. The setup performs display
hot-plugging once. If no display can be detected, DRM probe helpers
re-run the detection on each hotplug event.

A call to drm_dev_unregister() releases the client automatically.
No further action is required within i915. If the fbdev framebuffer
has been fully set up, struct fb_ops.fb_destroy implements the
release. For partially initialized emulation, the fbdev client
reverts the initial setup.

v6:
* use 'i915' for i915 device (Jouni)
* remove unnecessary code for non-atomic mode setting
  (Jouni, Ville)
* fix function name in commit message (Jouni)
v3:
* as before, silently ignore devices without displays
v2:
* let drm_client_register() handle initial hotplug
* fix driver name in error message (Jani)
* fix non-fbdev build (kernel test robot)

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/i915/display/intel_display.c  |   1 -
 .../drm/i915/display/intel_display_driver.c   |  18 --
 drivers/gpu/drm/i915/display/intel_fbdev.c| 177 --
 drivers/gpu/drm/i915/display/intel_fbdev.h|  20 +-
 drivers/gpu/drm/i915/i915_driver.c|   2 +
 5 files changed, 80 insertions(+), 138 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 28d85e1e858ea..7a8b50d6e52e1 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -82,7 +82,6 @@
 #include "intel_dvo.h"
 #include "intel_fb.h"
 #include "intel_fbc.h"
-#include "intel_fbdev.h"
 #include "intel_fdi.h"
 #include "intel_fifo_underrun.h"
 #include "intel_frontbuffer.h"
diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c 
b/drivers/gpu/drm/i915/display/intel_display_driver.c
index ffdcddd1943e0..213a4ee93ffc2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -364,10 +364,6 @@ int intel_display_driver_probe(struct drm_i915_private 
*i915)
 
intel_overlay_setup(i915);
 
-   ret = intel_fbdev_init(&i915->drm);
-   if (ret)
-   return ret;
-
/* Only enable hotplug handling once the fbdev is fully set up. */
intel_hpd_init(i915);
intel_hpd_poll_disable(i915);
@@ -392,16 +388,6 @@ void intel_display_driver_register(struct drm_i915_private 
*i915)
 
intel_display_debugfs_register(i915);
 
-   /*
-* Some ports require correctly set-up hpd registers for
-* detection to work properly (leading to ghost connected
-* connector status), e.g. VGA on gm45.  Hence we can only set
-* up the initial fbdev config after hpd irqs are fully
-* enabled. We do it last so that the async config cannot run
-* before the connectors are registered.
-*/
-   intel_fbdev_initial_config_async(i915);
-
/*
 * We need to coordinate the hotplugs with the asynchronous
 * fbdev configuration, for which we use the
@@ -445,9 +431,6 @@ void intel_display_driver_remove_noirq(struct 
drm_i915_private *i915)
 */
intel_hpd_poll_fini(i915);
 
-   /* poll work can call into fbdev, hence clean that up afterwards */
-   intel_fbdev_fini(i915);
-
intel_unregister_dsm_handler();
 
/* flush any delayed tasks or pending work */
@@ -484,7 +467,6 @@ void intel_display_driver_unregister(struct 
drm_i915_private *i915)
if (!HAS_DISPLAY(i915))
return;
 
-   intel_fbdev_unregister(i915);
intel_audio_deinit(i915);
 
/*
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 2837791613608..023c71cabe477 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -24,7 +24,6 @@
  * David Airlie
  */
 
-#include 
 #include 
 #include 
 #include 
@@ -39,6 +38,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -58,7 +58,6 @@ struct intel_fbdev {
struct intel_framebuffer *fb;
struct i915_vma *vma;
unsigned long vma_flags;
-   async_cookie_t cookie;
int preferred_bpp;
 
/* Whether or not fbdev hpd processing is temporarily suspended */
@@ -135,6 +134,26 @@ static int intel_fbdev_mmap(struct fb_info *info, struct 
vm_area_struct *vma)
return i915_gem_fb_mmap(obj, vma);
 }
 
+static void intel_fbdev_fb_destroy(struct fb_info *info)
+

[PATCH v6 5/7] drm/i915: Initialize fbdev DRM client with callback functions

2023-11-02 Thread Thomas Zimmermann
Initialize i915's fbdev client by giving an instance of struct
drm_client_funcs to drm_client_init(). Also clean up with
drm_client_release().

Doing this in i915 prevents fbdev helpers from initializing and
releasing the client internally (see drm_fb_helper_init()). No
functional change yet; the client callbacks will be filled later.

v6:
* rename client to "intel-fbdev" (Jouni)
v2:
* call drm_fb_helper_unprepare() in error handling (Jani)
* fix typo in commit message (Sam)

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/i915/display/intel_fbdev.c | 43 --
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 2695c65b55ddc..88c554ea7bb19 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -378,6 +378,7 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
if (ifbdev->fb)
drm_framebuffer_remove(&ifbdev->fb->base);
 
+   drm_client_release(&ifbdev->helper.client);
drm_fb_helper_unprepare(&ifbdev->helper);
kfree(ifbdev);
 }
@@ -671,6 +672,30 @@ void intel_fbdev_restore_mode(struct drm_i915_private 
*dev_priv)
intel_fbdev_invalidate(ifbdev);
 }
 
+/*
+ * Fbdev client and struct drm_client_funcs
+ */
+
+static void intel_fbdev_client_unregister(struct drm_client_dev *client)
+{ }
+
+static int intel_fbdev_client_restore(struct drm_client_dev *client)
+{
+   return 0;
+}
+
+static int intel_fbdev_client_hotplug(struct drm_client_dev *client)
+{
+   return 0;
+}
+
+static const struct drm_client_funcs intel_fbdev_client_funcs = {
+   .owner  = THIS_MODULE,
+   .unregister = intel_fbdev_client_unregister,
+   .restore= intel_fbdev_client_restore,
+   .hotplug= intel_fbdev_client_hotplug,
+};
+
 int intel_fbdev_init(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = to_i915(dev);
@@ -692,16 +717,26 @@ int intel_fbdev_init(struct drm_device *dev)
else
ifbdev->preferred_bpp = ifbdev->helper.preferred_bpp;
 
+   ret = drm_client_init(dev, &ifbdev->helper.client, "intel-fbdev",
+ &intel_fbdev_client_funcs);
+   if (ret)
+   goto err_drm_fb_helper_unprepare;
+
ret = drm_fb_helper_init(dev, &ifbdev->helper);
-   if (ret) {
-   kfree(ifbdev);
-   return ret;
-   }
+   if (ret)
+   goto err_drm_client_release;
 
dev_priv->display.fbdev.fbdev = ifbdev;
INIT_WORK(&dev_priv->display.fbdev.suspend_work, 
intel_fbdev_suspend_worker);
 
return 0;
+
+err_drm_client_release:
+   drm_client_release(&ifbdev->helper.client);
+err_drm_fb_helper_unprepare:
+   drm_fb_helper_unprepare(&ifbdev->helper);
+   kfree(ifbdev);
+   return ret;
 }
 
 static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
-- 
2.42.0



Re: [PATCH drm-misc-next v8 12/12] drm/nouveau: use GPUVM common infrastructure

2023-11-02 Thread Thomas Hellström
On Thu, 2023-11-02 at 00:31 +0100, Danilo Krummrich wrote:
> GPUVM provides common infrastructure to track external and evicted
> GEM
> objects as well as locking and validation helpers.
> 
> Especially external and evicted object tracking is a huge improvement
> compared to the current brute force approach of iterating all
> mappings
> in order to lock and validate the GPUVM's GEM objects. Hence, make us
> of
> it.
> 
> Signed-off-by: Danilo Krummrich 
NIT: Multiple checkpatch warnings in this one.

> ---
>  drivers/gpu/drm/nouveau/nouveau_bo.c    |  4 +-
>  drivers/gpu/drm/nouveau/nouveau_exec.c  | 57 --
>  drivers/gpu/drm/nouveau/nouveau_exec.h  |  4 -
>  drivers/gpu/drm/nouveau/nouveau_sched.c |  9 ++-
>  drivers/gpu/drm/nouveau/nouveau_sched.h |  7 +-
>  drivers/gpu/drm/nouveau/nouveau_uvmm.c  | 99 ---
> --
>  6 files changed, 90 insertions(+), 90 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c
> b/drivers/gpu/drm/nouveau/nouveau_bo.c
> index 7afad86da64b..b7dda486a7ea 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_bo.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
> @@ -1061,17 +1061,18 @@ nouveau_bo_move(struct ttm_buffer_object *bo,
> bool evict,
>  {
> struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
> struct nouveau_bo *nvbo = nouveau_bo(bo);
> +   struct drm_gem_object *obj = &bo->base;
> struct ttm_resource *old_reg = bo->resource;
> struct nouveau_drm_tile *new_tile = NULL;
> int ret = 0;
>  
> -
> if (new_reg->mem_type == TTM_PL_TT) {
> ret = nouveau_ttm_tt_bind(bo->bdev, bo->ttm,
> new_reg);
> if (ret)
> return ret;
> }
>  
> +   drm_gpuvm_bo_gem_evict(obj, evict);
> nouveau_bo_move_ntfy(bo, new_reg);
> ret = ttm_bo_wait_ctx(bo, ctx);
> if (ret)
> @@ -1136,6 +1137,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo,
> bool evict,
>  out_ntfy:
> if (ret) {
> nouveau_bo_move_ntfy(bo, bo->resource);
> +   drm_gpuvm_bo_gem_evict(obj, !evict);
> }
> return ret;
>  }
> diff --git a/drivers/gpu/drm/nouveau/nouveau_exec.c
> b/drivers/gpu/drm/nouveau/nouveau_exec.c
> index bf6c12f4342a..9d9835fb5970 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_exec.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_exec.c
> @@ -1,7 +1,5 @@
>  // SPDX-License-Identifier: MIT
>  
> -#include 
> -
>  #include "nouveau_drv.h"
>  #include "nouveau_gem.h"
>  #include "nouveau_mem.h"
> @@ -86,14 +84,12 @@
>   */
>  
>  static int
> -nouveau_exec_job_submit(struct nouveau_job *job)
> +nouveau_exec_job_submit(struct nouveau_job *job,
> +   struct drm_gpuvm_exec *vme)
>  {
> struct nouveau_exec_job *exec_job = to_nouveau_exec_job(job);
> struct nouveau_cli *cli = job->cli;
> struct nouveau_uvmm *uvmm = nouveau_cli_uvmm(cli);
> -   struct drm_exec *exec = &job->exec;
> -   struct drm_gem_object *obj;
> -   unsigned long index;
> int ret;
>  
> /* Create a new fence, but do not emit yet. */
> @@ -102,52 +98,29 @@ nouveau_exec_job_submit(struct nouveau_job *job)
> return ret;
>  
> nouveau_uvmm_lock(uvmm);
> -   drm_exec_init(exec, DRM_EXEC_INTERRUPTIBLE_WAIT |
> -   DRM_EXEC_IGNORE_DUPLICATES);
> -   drm_exec_until_all_locked(exec) {
> -   struct drm_gpuva *va;
> -
> -   drm_gpuvm_for_each_va(va, &uvmm->base) {
> -   if (unlikely(va == &uvmm-
> >base.kernel_alloc_node))
> -   continue;
> -
> -   ret = drm_exec_prepare_obj(exec, va->gem.obj,
> 1);
> -   drm_exec_retry_on_contention(exec);
> -   if (ret)
> -   goto err_uvmm_unlock;
> -   }
> +   ret = drm_gpuvm_exec_lock(vme);
> +   if (ret) {
> +   nouveau_uvmm_unlock(uvmm);
> +   return ret;
> }
> nouveau_uvmm_unlock(uvmm);
>  
> -   drm_exec_for_each_locked_object(exec, index, obj) {
> -   struct nouveau_bo *nvbo = nouveau_gem_object(obj);
> -
> -   ret = nouveau_bo_validate(nvbo, true, false);
> -   if (ret)
> -   goto err_exec_fini;
> +   ret = drm_gpuvm_exec_validate(vme);
> +   if (ret) {
> +   drm_gpuvm_exec_unlock(vme);
> +   return ret;
> }
>  
> return 0;
> -
> -err_uvmm_unlock:
> -   nouveau_uvmm_unlock(uvmm);
> -err_exec_fini:
> -   drm_exec_fini(exec);
> -   return ret;
> -
>  }
>  
>  static void
> -nouveau_exec_job_armed_submit(struct nouveau_job *job)
> +nouveau_exec_job_armed_submit(struct nouveau_job *job,
> + struct drm_gpuvm_exec *vme)
>  {
> -   struct drm_exec *exec = &job->exec;
> -   struct drm_gem_object *obj;
> -   unsign

Re: [PATCH drm-misc-next v8 02/12] drm/gpuvm: don't always WARN in drm_gpuvm_check_overflow()

2023-11-02 Thread Thomas Hellström
On Thu, 2023-11-02 at 00:30 +0100, Danilo Krummrich wrote:
> Don't always WARN in drm_gpuvm_check_overflow() and separate it into
> a
> drm_gpuvm_check_overflow() and a dedicated
> drm_gpuvm_warn_check_overflow() variant.
> 
> This avoids printing warnings due to invalid userspace requests.
> 
> Signed-off-by: Danilo Krummrich 
Reviewed-by: Thomas Hellström 

> ---
>  drivers/gpu/drm/drm_gpuvm.c | 20 +---
>  1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gpuvm.c
> b/drivers/gpu/drm/drm_gpuvm.c
> index d7367a202fee..445767f8fbc4 100644
> --- a/drivers/gpu/drm/drm_gpuvm.c
> +++ b/drivers/gpu/drm/drm_gpuvm.c
> @@ -614,12 +614,18 @@ static int __drm_gpuva_insert(struct drm_gpuvm
> *gpuvm,
>  static void __drm_gpuva_remove(struct drm_gpuva *va);
>  
>  static bool
> -drm_gpuvm_check_overflow(struct drm_gpuvm *gpuvm, u64 addr, u64
> range)
> +drm_gpuvm_check_overflow(u64 addr, u64 range)
>  {
> u64 end;
>  
> -   return drm_WARN(gpuvm->drm, check_add_overflow(addr, range,
> &end),
> -   "GPUVA address limited to %zu bytes.\n",
> sizeof(end));
> +   return check_add_overflow(addr, range, &end);
> +}
> +
> +static bool
> +drm_gpuvm_warn_check_overflow(struct drm_gpuvm *gpuvm, u64 addr, u64
> range)
> +{
> +   return drm_WARN(gpuvm->drm, drm_gpuvm_check_overflow(addr,
> range),
> +   "GPUVA address limited to %zu bytes.\n",
> sizeof(addr));
>  }
>  
>  static bool
> @@ -647,7 +653,7 @@ static bool
>  drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm,
>   u64 addr, u64 range)
>  {
> -   return !drm_gpuvm_check_overflow(gpuvm, addr, range) &&
> +   return !drm_gpuvm_check_overflow(addr, range) &&
>    drm_gpuvm_in_mm_range(gpuvm, addr, range) &&
>    !drm_gpuvm_in_kernel_node(gpuvm, addr, range);
>  }
> @@ -682,7 +688,7 @@ drm_gpuvm_init(struct drm_gpuvm *gpuvm, const
> char *name,
> gpuvm->ops = ops;
> gpuvm->drm = drm;
>  
> -   drm_gpuvm_check_overflow(gpuvm, start_offset, range);
> +   drm_gpuvm_warn_check_overflow(gpuvm, start_offset, range);
> gpuvm->mm_start = start_offset;
> gpuvm->mm_range = range;
>  
> @@ -691,8 +697,8 @@ drm_gpuvm_init(struct drm_gpuvm *gpuvm, const
> char *name,
> gpuvm->kernel_alloc_node.va.addr = reserve_offset;
> gpuvm->kernel_alloc_node.va.range = reserve_range;
>  
> -   if (likely(!drm_gpuvm_check_overflow(gpuvm,
> reserve_offset,
> -    reserve_range)))
> +   if (likely(!drm_gpuvm_warn_check_overflow(gpuvm,
> reserve_offset,
> +
> reserve_range)))
> __drm_gpuva_insert(gpuvm, &gpuvm-
> >kernel_alloc_node);
> }
>  }



Re: [PATCH drm-misc-next v8 03/12] drm/gpuvm: export drm_gpuvm_range_valid()

2023-11-02 Thread Thomas Hellström
On Thu, 2023-11-02 at 00:30 +0100, Danilo Krummrich wrote:
> Drivers may use this function to validate userspace requests in
> advance,
> hence export it.
> 
> Signed-off-by: Danilo Krummrich 
Reviewed-by: Thomas Hellström 

> ---
>  drivers/gpu/drm/drm_gpuvm.c | 14 +-
>  include/drm/drm_gpuvm.h |  1 +
>  2 files changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_gpuvm.c
> b/drivers/gpu/drm/drm_gpuvm.c
> index 445767f8fbc4..2669f9bbc377 100644
> --- a/drivers/gpu/drm/drm_gpuvm.c
> +++ b/drivers/gpu/drm/drm_gpuvm.c
> @@ -649,7 +649,18 @@ drm_gpuvm_in_kernel_node(struct drm_gpuvm
> *gpuvm, u64 addr, u64 range)
> return krange && addr < kend && kstart < end;
>  }
>  
> -static bool
> +/**
> + * drm_gpuvm_range_valid() - checks whether the given range is valid
> for the
> + * given &drm_gpuvm
> + * @gpuvm: the GPUVM to check the range for
> + * @addr: the base address
> + * @range: the range starting from the base address
> + *
> + * Checks whether the range is within the GPUVM's managed
> boundaries.
> + *
> + * Returns: true for a valid range, false otherwise
> + */
> +bool
>  drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm,
>   u64 addr, u64 range)
>  {
> @@ -657,6 +668,7 @@ drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm,
>    drm_gpuvm_in_mm_range(gpuvm, addr, range) &&
>    !drm_gpuvm_in_kernel_node(gpuvm, addr, range);
>  }
> +EXPORT_SYMBOL_GPL(drm_gpuvm_range_valid);
>  
>  /**
>   * drm_gpuvm_init() - initialize a &drm_gpuvm
> diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
> index 687fd5893624..13eac6f70061 100644
> --- a/include/drm/drm_gpuvm.h
> +++ b/include/drm/drm_gpuvm.h
> @@ -253,6 +253,7 @@ void drm_gpuvm_init(struct drm_gpuvm *gpuvm,
> const char *name,
>     const struct drm_gpuvm_ops *ops);
>  void drm_gpuvm_destroy(struct drm_gpuvm *gpuvm);
>  
> +bool drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm, u64 addr, u64
> range);
>  bool drm_gpuvm_interval_empty(struct drm_gpuvm *gpuvm, u64 addr, u64
> range);
>  
>  static inline struct drm_gpuva *



Re: [PATCH drm-misc-next v8 09/12] drm/gpuvm: reference count drm_gpuvm structures

2023-11-02 Thread Thomas Hellström
On Thu, 2023-11-02 at 00:31 +0100, Danilo Krummrich wrote:
> Implement reference counting for struct drm_gpuvm.
> 
> Signed-off-by: Danilo Krummrich 

Will port the Xe series over to check that it works properly and get
back with review on this one.


> ---
>  drivers/gpu/drm/drm_gpuvm.c    | 44 +++-
> --
>  drivers/gpu/drm/nouveau/nouveau_uvmm.c | 20 +---
>  include/drm/drm_gpuvm.h    | 31 +-
>  3 files changed, 78 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gpuvm.c
> b/drivers/gpu/drm/drm_gpuvm.c
> index 53e2c406fb04..6a88eafc5229 100644
> --- a/drivers/gpu/drm/drm_gpuvm.c
> +++ b/drivers/gpu/drm/drm_gpuvm.c
> @@ -746,6 +746,8 @@ drm_gpuvm_init(struct drm_gpuvm *gpuvm, const
> char *name,
> gpuvm->rb.tree = RB_ROOT_CACHED;
> INIT_LIST_HEAD(&gpuvm->rb.list);
>  
> +   kref_init(&gpuvm->kref);
> +
> gpuvm->name = name ? name : "unknown";
> gpuvm->flags = flags;
> gpuvm->ops = ops;
> @@ -770,15 +772,8 @@ drm_gpuvm_init(struct drm_gpuvm *gpuvm, const
> char *name,
>  }
>  EXPORT_SYMBOL_GPL(drm_gpuvm_init);
>  
> -/**
> - * drm_gpuvm_destroy() - cleanup a &drm_gpuvm
> - * @gpuvm: pointer to the &drm_gpuvm to clean up
> - *
> - * Note that it is a bug to call this function on a manager that
> still
> - * holds GPU VA mappings.
> - */
> -void
> -drm_gpuvm_destroy(struct drm_gpuvm *gpuvm)
> +static void
> +drm_gpuvm_fini(struct drm_gpuvm *gpuvm)
>  {
> gpuvm->name = NULL;
>  
> @@ -790,7 +785,33 @@ drm_gpuvm_destroy(struct drm_gpuvm *gpuvm)
>  
> drm_gem_object_put(gpuvm->r_obj);
>  }
> -EXPORT_SYMBOL_GPL(drm_gpuvm_destroy);
> +
> +static void
> +drm_gpuvm_free(struct kref *kref)
> +{
> +   struct drm_gpuvm *gpuvm = container_of(kref, struct
> drm_gpuvm, kref);
> +
> +   if (drm_WARN_ON(gpuvm->drm, !gpuvm->ops->vm_free))
> +   return;
> +
> +   drm_gpuvm_fini(gpuvm);
> +
> +   gpuvm->ops->vm_free(gpuvm);
> +}
> +
> +/**
> + * drm_gpuvm_bo_put() - drop a struct drm_gpuvm reference
> + * @gpuvm: the &drm_gpuvm to release the reference of
> + *
> + * This releases a reference to @gpuvm.
> + */
> +void
> +drm_gpuvm_put(struct drm_gpuvm *gpuvm)
> +{
> +   if (gpuvm)
> +   kref_put(&gpuvm->kref, drm_gpuvm_free);
> +}
> +EXPORT_SYMBOL_GPL(drm_gpuvm_put);
>  
>  static int
>  __drm_gpuva_insert(struct drm_gpuvm *gpuvm,
> @@ -843,7 +864,7 @@ drm_gpuva_insert(struct drm_gpuvm *gpuvm,
> if (unlikely(!drm_gpuvm_range_valid(gpuvm, addr, range)))
> return -EINVAL;
>  
> -   return __drm_gpuva_insert(gpuvm, va);
> +   return __drm_gpuva_insert(drm_gpuvm_get(gpuvm), va);
>  }
>  EXPORT_SYMBOL_GPL(drm_gpuva_insert);
>  
> @@ -876,6 +897,7 @@ drm_gpuva_remove(struct drm_gpuva *va)
> }
>  
> __drm_gpuva_remove(va);
> +   drm_gpuvm_put(va->vm);
>  }
>  EXPORT_SYMBOL_GPL(drm_gpuva_remove);
>  
> diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> index 54be12c1272f..cb2f06565c46 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> @@ -1780,6 +1780,18 @@ nouveau_uvmm_bo_unmap_all(struct nouveau_bo
> *nvbo)
> }
>  }
>  
> +static void
> +nouveau_uvmm_free(struct drm_gpuvm *gpuvm)
> +{
> +   struct nouveau_uvmm *uvmm = uvmm_from_gpuvm(gpuvm);
> +
> +   kfree(uvmm);
> +}
> +
> +static const struct drm_gpuvm_ops gpuvm_ops = {
> +   .vm_free = nouveau_uvmm_free,
> +};
> +
>  int
>  nouveau_uvmm_ioctl_vm_init(struct drm_device *dev,
>    void *data,
> @@ -1830,7 +1842,7 @@ nouveau_uvmm_ioctl_vm_init(struct drm_device
> *dev,
>    NOUVEAU_VA_SPACE_END,
>    init->kernel_managed_addr,
>    init->kernel_managed_size,
> -  NULL);
> +  &gpuvm_ops);
> /* GPUVM takes care from here on. */
> drm_gem_object_put(r_obj);
>  
> @@ -1849,8 +1861,7 @@ nouveau_uvmm_ioctl_vm_init(struct drm_device
> *dev,
> return 0;
>  
>  out_gpuvm_fini:
> -   drm_gpuvm_destroy(&uvmm->base);
> -   kfree(uvmm);
> +   drm_gpuvm_put(&uvmm->base);
>  out_unlock:
> mutex_unlock(&cli->mutex);
> return ret;
> @@ -1902,7 +1913,6 @@ nouveau_uvmm_fini(struct nouveau_uvmm *uvmm)
>  
> mutex_lock(&cli->mutex);
> nouveau_vmm_fini(&uvmm->vmm);
> -   drm_gpuvm_destroy(&uvmm->base);
> -   kfree(uvmm);
> +   drm_gpuvm_put(&uvmm->base);
> mutex_unlock(&cli->mutex);
>  }
> diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
> index 0c2e24155a93..4e6e1fd3485a 100644
> --- a/include/drm/drm_gpuvm.h
> +++ b/include/drm/drm_gpuvm.h
> @@ -247,6 +247,11 @@ struct drm_gpuvm {
> struct list_head list;
> } rb;
>  
> +   /**
> +    * @kref: reference count of this object
> +    */
> +   

Re: [RFC 03/11] drm: introduce drm evictable LRU

2023-11-02 Thread Christian König

Am 02.11.23 um 05:32 schrieb Oak Zeng:

drm LRU manager is introuced for resource eviction purpose. It maintains
a LRU list per resource type.


Shouldn't we first add the possible resource types in a separate patch?


  It provides functions to add or remove
resource to or from the list. It also provides function to retrieve the
first entity on the LRU list.


+ functions to iterate over them.



drm LRU manager also provides functions for bulk moving resources
on the LRU lists.

drm LRU manager also does very basic memory accounting function, i.e.,
LRU manager keeps a size of this resource type and a usage member
for how much of resource has been added to this LRU manager's LRU
list. TTM resource manager memory accounting functoins such as
struct ttm_resource_manager::size and struct ttm_resource_manger::usage
are still kept. In the future, when SVM codes are in the picture,
those memory accounting functions need some rework to consider
the memory used by both TTM and SVM.


Please keep in mind that this structure needs to extremely small to be 
usable for SVM. E.g. struct page size small :)


At least HMM based implementations ideally wants to have one for each 
page or something like that.



For one device, a global drm LRU manager per resource type should be
created/initialized at device initialization time. Drm LRU manager
instances are embedded in struct drm_device.

It is pretty much moving some of the ttm resource manager functions
to the drm layer. The reason of this code refactory is, we want to
create a single LRU list for memory allocated from BO(buffer object)
based driver and hmm/svm(shared virtual memory) based driver, thus BO
driver and svm driver can evict memory from each other.

Previously the LRU list in TTM resource manager (lru field in struct
ttm_reource_manager) is coupled with ttm_buffer_object concept, i.e.,
each ttm resource is backed by a ttm_buffer_object and the LRU list
is essentially a list of ttm_buffer_object.


Actually it's the other way around. The resource provides the backing of 
the BO.


And when a BO moves around it can temporary be that multiple resource 
point to the same BO.


I also want to have a more advanced iterator at some point where we grab 
the BO lock for keeping a reference into the LRU list. Not sure how to 
do this if we don't have the BO here any more.


Need to think about that further,
Christian.


  Due to this behavior, the
TTM resource manager can't be used by hmm/svm driver as we don't plan
to have the BO concept for the hmm/svm implemenation. So we decouple
the evictable LRU list from the BO concept in this series.

The design goal of drm lru manager is to make it as lean as possible.
So each lru entity only has a list node member used to link this entity
to the evictable LRU list, and the basic resource size/type/priority
of this entity. It doesn't have any driver specify information. A lru
entity also has a function pointer of evict function. This is used to
implement ttm or svm specific eviction function. A lru entity is supposed
to be embedded in a driver specific structure such as struct
ttm_resource, see the usage in the next patch of this series.

The ttm resource manager, and some of the ttm_bo functions such as
ttm_mem_evict_first will be rewriten using the new drm lru manager
library, see the next patch in this series.

The future hmm/svm implemenation will call lru manager function to add
hmm/svm allocations to the shared evictable lru list.

Lock design: previously ttm_resource LRU list is protected by a device
global ttm_device::lru_lock (bdev->lru_lock in codes). This lock also
protects ttm_buffer_object::pin_count, ttm_resource_manager::usage,
ttm_resource::bo, ttm_device::pinned list etc. With this refactory,
lru_lock is moved out of ttm_device and is added to struct drm_deive, so
it can be shared b/t ttm code and svm code.

Signed-off-by: Oak Zeng 
---
  drivers/gpu/drm/Makefile|   1 +
  drivers/gpu/drm/drm_evictable_lru.c | 232 
  include/drm/drm_device.h|   7 +
  include/drm/drm_evictable_lru.h | 188 ++
  4 files changed, 428 insertions(+)
  create mode 100644 drivers/gpu/drm/drm_evictable_lru.c
  create mode 100644 include/drm/drm_evictable_lru.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 1ad88efb1752..13953b0d271b 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -46,6 +46,7 @@ drm-y := \
drm_vblank_work.o \
drm_vma_manager.o \
drm_gpuva_mgr.o \
+   drm_evictable_lru.o \
drm_writeback.o
  drm-$(CONFIG_DRM_LEGACY) += \
drm_agpsupport.o \
diff --git a/drivers/gpu/drm/drm_evictable_lru.c 
b/drivers/gpu/drm/drm_evictable_lru.c
new file mode 100644
index ..2ba9105cca03
--- /dev/null
+++ b/drivers/gpu/drm/drm_evictable_lru.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include 
+#include

Re: [PATCH drm-misc-next v8 10/12] drm/gpuvm: add an abstraction for a VM / BO combination

2023-11-02 Thread Thomas Hellström
On Thu, 2023-11-02 at 00:31 +0100, Danilo Krummrich wrote:
> Add an abstraction layer between the drm_gpuva mappings of a
> particular
> drm_gem_object and this GEM object itself. The abstraction represents
> a
> combination of a drm_gem_object and drm_gpuvm. The drm_gem_object
> holds
> a list of drm_gpuvm_bo structures (the structure representing this
> abstraction), while each drm_gpuvm_bo contains list of mappings of
> this
> GEM object.
> 
> This has multiple advantages:
> 
> 1) We can use the drm_gpuvm_bo structure to attach it to various
> lists
>    of the drm_gpuvm. This is useful for tracking external and evicted
>    objects per VM, which is introduced in subsequent patches.
> 
> 2) Finding mappings of a certain drm_gem_object mapped in a certain
>    drm_gpuvm becomes much cheaper.
> 
> 3) Drivers can derive and extend the structure to easily represent
>    driver specific states of a BO for a certain GPUVM.
> 
> The idea of this abstraction was taken from amdgpu, hence the credit
> for
> this idea goes to the developers of amdgpu.
> 
> Cc: Christian König 
> Reviewed-by: Boris Brezillon 
> Signed-off-by: Danilo Krummrich 
Reviewed-by: Thomas Hellström 

> ---
>  drivers/gpu/drm/drm_gpuvm.c    | 336 +--
> --
>  drivers/gpu/drm/nouveau/nouveau_uvmm.c |  63 +++--
>  include/drm/drm_gem.h  |  32 +--
>  include/drm/drm_gpuvm.h    | 185 +-
>  4 files changed, 530 insertions(+), 86 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gpuvm.c
> b/drivers/gpu/drm/drm_gpuvm.c
> index 6a88eafc5229..2c8fdefb19f0 100644
> --- a/drivers/gpu/drm/drm_gpuvm.c
> +++ b/drivers/gpu/drm/drm_gpuvm.c
> @@ -70,6 +70,18 @@
>   * &drm_gem_object, such as the &drm_gem_object containing the root
> page table,
>   * but it can also be a 'dummy' object, which can be allocated with
>   * drm_gpuvm_resv_object_alloc().
> + *
> + * In order to connect a struct drm_gpuva its backing
> &drm_gem_object each
> + * &drm_gem_object maintains a list of &drm_gpuvm_bo structures, and
> each
> + * &drm_gpuvm_bo contains a list of &drm_gpuva structures.
> + *
> + * A &drm_gpuvm_bo is an abstraction that represents a combination
> of a
> + * &drm_gpuvm and a &drm_gem_object. Every such combination should
> be unique.
> + * This is ensured by the API through drm_gpuvm_bo_obtain() and
> + * drm_gpuvm_bo_obtain_prealloc() which first look into the
> corresponding
> + * &drm_gem_object list of &drm_gpuvm_bos for an existing instance
> of this
> + * particular combination. If not existent a new instance is created
> and linked
> + * to the &drm_gem_object.
>   */
>  
>  /**
> @@ -395,21 +407,28 @@
>  /**
>   * DOC: Locking
>   *
> - * Generally, the GPU VA manager does not take care of locking
> itself, it is
> - * the drivers responsibility to take care about locking. Drivers
> might want to
> - * protect the following operations: inserting, removing and
> iterating
> - * &drm_gpuva objects as well as generating all kinds of operations,
> such as
> - * split / merge or prefetch.
> - *
> - * The GPU VA manager also does not take care of the locking of the
> backing
> - * &drm_gem_object buffers GPU VA lists by itself; drivers are
> responsible to
> - * enforce mutual exclusion using either the GEMs dma_resv lock or
> alternatively
> - * a driver specific external lock. For the latter see also
> - * drm_gem_gpuva_set_lock().
> - *
> - * However, the GPU VA manager contains lockdep checks to ensure
> callers of its
> - * API hold the corresponding lock whenever the &drm_gem_objects GPU
> VA list is
> - * accessed by functions such as drm_gpuva_link() or
> drm_gpuva_unlink().
> + * In terms of managing &drm_gpuva entries DRM GPUVM does not take
> care of
> + * locking itself, it is the drivers responsibility to take care
> about locking.
> + * Drivers might want to protect the following operations:
> inserting, removing
> + * and iterating &drm_gpuva objects as well as generating all kinds
> of
> + * operations, such as split / merge or prefetch.
> + *
> + * DRM GPUVM also does not take care of the locking of the backing
> + * &drm_gem_object buffers GPU VA lists and &drm_gpuvm_bo
> abstractions by
> + * itself; drivers are responsible to enforce mutual exclusion using
> either the
> + * GEMs dma_resv lock or alternatively a driver specific external
> lock. For the
> + * latter see also drm_gem_gpuva_set_lock().
> + *
> + * However, DRM GPUVM contains lockdep checks to ensure callers of
> its API hold
> + * the corresponding lock whenever the &drm_gem_objects GPU VA list
> is accessed
> + * by functions such as drm_gpuva_link() or drm_gpuva_unlink(), but
> also
> + * drm_gpuvm_bo_obtain() and drm_gpuvm_bo_put().
> + *
> + * The latter is required since on creation and destruction of a
> &drm_gpuvm_bo
> + * the &drm_gpuvm_bo is attached / removed from the &drm_gem_objects
> gpuva list.
> + * Subsequent calls to drm_gpuvm_bo_obtain() for the same &drm_gpuvm
> and
> + * &drm_gem_obje

Re: [PATCH] drm/amdgpu: don't put MQDs in VRAM on ARM | ARM64

2023-11-02 Thread Christian König

Am 31.10.23 um 18:54 schrieb Alex Deucher:

Issues were reported with commit 1cfb4d612127
("drm/amdgpu: put MQDs in VRAM") on an ADLINK Ampere
Altra Developer Platform (AVA developer platform).

Various ARM systems seem to have problems related
to PCIe and MMIO access.  In this case, I'm not sure
if this is specific to the ADLINK platform or ARM
in general.  Seems to be some coherency issue with
VRAM.  For now, just don't put MQDs in VRAM on ARM.

Link: https://lists.freedesktop.org/archives/amd-gfx/2023-October/100453.html
Fixes: 1cfb4d612127 ("drm/amdgpu: put MQDs in VRAM")
Signed-off-by: Alex Deucher 
Cc: alexey.kli...@linaro.org


Acked-by: Christian König 


---
  drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index c92e0aba69e1..a2a29dcb2422 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -385,9 +385,11 @@ int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
struct amdgpu_ring *ring = &kiq->ring;
u32 domain = AMDGPU_GEM_DOMAIN_GTT;
  
+#if !defined(CONFIG_ARM) && !defined(CONFIG_ARM64)

/* Only enable on gfx10 and 11 for now to avoid changing behavior on 
older chips */
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 0, 0))
domain |= AMDGPU_GEM_DOMAIN_VRAM;
+#endif
  
  	/* create MQD for KIQ */

if (!adev->enable_mes_kiq && !ring->mqd_obj) {




Re: [PATCH] gpu/drm/drm_framebuffer.c: Use Macro instead of actual number.

2023-11-02 Thread Thomas Zimmermann

Hi

Am 02.11.23 um 03:29 schrieb Peng Hao:

Use Macro DRM_FORMAT_MAX_PLANES instead of 4, to improve modifiability.

Signed-off-by: Peng Hao 
---
  drivers/gpu/drm/drm_framebuffer.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_framebuffer.c 
b/drivers/gpu/drm/drm_framebuffer.c
index 2dd97473ca10..bf283dae9090 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -254,7 +254,7 @@ static int framebuffer_check(struct drm_device *dev,
}
}
  
-	for (i = info->num_planes; i < 4; i++) {

+   for (i = info->num_planes; i < DRM_FORMAT_MAX_PLANES; i++) {


This change makes the code more fragile. '4' is a fixed constant in the 
UAPI struct, while DRM_FORMAT_MAX_PLANES is an internal constant. I 
agree that both should reasonably have the same value. But (potentially) 
changing the value of DRM_FORMAT_MAX_PLANES will break these loops with 
a possible OOB access.


To make make this code more robust, it might be better to rewrite the 
tests like this


for (i = num_planes; i < ARRAY_SIZE(r->modifier); +i) {
// the test for modifier[i]
}

if (r->flags & DRM_MODE_FB_MODIFIERS) {
for (i < ARRAY_SIZE(handles)) {
// test for handles[i]
}
for (i < ARRAY_SIZE(pitches)) {
// test for pitches[i]
}
for (i < ARRAY_SIZE(offsets)) {
// test for offsets[i]
}
}

Best regards
Thomas


if (r->modifier[i]) {
drm_dbg_kms(dev, "non-zero modifier for unused plane 
%d\n", i);
return -EINVAL;


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


OpenPGP_signature.asc
Description: OpenPGP digital signature


[PULL] drm-misc-next-fixes

2023-11-02 Thread Maarten Lankhorst

Hi Daniel, Dave,

Just 2 small ssd130x fixes.

Cheers,
~Maarten

drm-misc-next-fixes-2023-11-02:
drm-misc-next-fixes for v6.7-rc1:

- dt binding fix for ssd132x
- Initialize ssd130x crtc_state to NULL.

The following changes since commit b70438004a14f4d0f9890b3297cd66248728546c:

  drm/amdgpu: move buffer funcs setting up a level (2023-10-26 16:04:24 
-0400)


are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-misc 
tags/drm-misc-next-fixes-2023-11-02


for you to fetch changes up to 94565e95e247c188fed4d3da1034402f3fb297de:

  drm/ssd130x: Fix possible uninitialized usage of crtc_state variable 
(2023-10-30 11:00:27 +0100)



drm-misc-next-fixes for v6.7-rc1:

- dt binding fix for ssd132x
- Initialize ssd130x crtc_state to NULL.


Javier Martinez Canillas (2):
  dt-bindings: display: ssd132x: Remove '-' before compatible enum
  drm/ssd130x: Fix possible uninitialized usage of crtc_state variable

 Documentation/devicetree/bindings/display/solomon,ssd132x.yaml | 8 


 drivers/gpu/drm/solomon/ssd130x.c  | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)


[PATCH v1 0/4] Rockchip rk3066_hdmi update

2023-11-02 Thread Johan Jonker
Update the Rockchip rk3066_hdmi driver in a somewhat similar way
to what is proposed for the inno_hdmi driver.

Johan Jonker (4):
  drm/rockchip: rk3066_hdmi: Remove useless mode_fixup
  drm/rockchip: rk3066_hdmi: Switch encoder hooks to atomic
  drm/rockchip: rk3066_hdmi: Remove useless output format
  drm/rockchip: rk3066_hdmi: Remove unused drm device pointer

 drivers/gpu/drm/rockchip/rk3066_hdmi.c | 66 +++---
 1 file changed, 18 insertions(+), 48 deletions(-)

--
2.39.2



[PATCH v1 1/4] drm/rockchip: rk3066_hdmi: Remove useless mode_fixup

2023-11-02 Thread Johan Jonker
The mode_fixup implementation doesn't do anything, so we can simply
remove it.

Signed-off-by: Johan Jonker 
---
 drivers/gpu/drm/rockchip/rk3066_hdmi.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c 
b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
index fa6e592e0276..5c269081c691 100644
--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
@@ -434,14 +434,6 @@ static void rk3066_hdmi_encoder_disable(struct drm_encoder 
*encoder)
rk3066_hdmi_set_power_mode(hdmi, HDMI_SYS_POWER_MODE_A);
 }

-static bool
-rk3066_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
-  const struct drm_display_mode *mode,
-  struct drm_display_mode *adj_mode)
-{
-   return true;
-}
-
 static int
 rk3066_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 struct drm_crtc_state *crtc_state,
@@ -459,7 +451,6 @@ static const
 struct drm_encoder_helper_funcs rk3066_hdmi_encoder_helper_funcs = {
.enable   = rk3066_hdmi_encoder_enable,
.disable  = rk3066_hdmi_encoder_disable,
-   .mode_fixup   = rk3066_hdmi_encoder_mode_fixup,
.mode_set = rk3066_hdmi_encoder_mode_set,
.atomic_check = rk3066_hdmi_encoder_atomic_check,
 };
--
2.39.2



[PATCH v1 2/4] drm/rockchip: rk3066_hdmi: Switch encoder hooks to atomic

2023-11-02 Thread Johan Jonker
The rk3066_hdmi encoder still uses the non atomic variants
of enable and disable. Convert to their atomic equivalents.
In atomic mode there is no need to save the adjusted mode,
so remove the mode_set function.

Signed-off-by: Johan Jonker 
---
 drivers/gpu/drm/rockchip/rk3066_hdmi.c | 35 +-
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c 
b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
index 5c269081c691..0e7aae341960 100644
--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
@@ -55,7 +55,6 @@ struct rk3066_hdmi {
unsigned int tmdsclk;

struct hdmi_data_info hdmi_data;
-   struct drm_display_mode previous_mode;
 };

 static struct rk3066_hdmi *encoder_to_rk3066_hdmi(struct drm_encoder *encoder)
@@ -387,21 +386,21 @@ static int rk3066_hdmi_setup(struct rk3066_hdmi *hdmi,
return 0;
 }

-static void
-rk3066_hdmi_encoder_mode_set(struct drm_encoder *encoder,
-struct drm_display_mode *mode,
-struct drm_display_mode *adj_mode)
+static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder,
+  struct drm_atomic_state *state)
 {
struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder);
+   struct drm_connector_state *conn_state;
+   struct drm_crtc_state *crtc_state;
+   int mux, val;

-   /* Store the display mode for plugin/DPMS poweron events. */
-   drm_mode_copy(&hdmi->previous_mode, adj_mode);
-}
+   conn_state = drm_atomic_get_new_connector_state(state, 
&hdmi->connector);
+   if (WARN_ON(!conn_state))
+   return;

-static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder)
-{
-   struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder);
-   int mux, val;
+   crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+   if (WARN_ON(!crtc_state))
+   return;

mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
if (mux)
@@ -414,10 +413,11 @@ static void rk3066_hdmi_encoder_enable(struct drm_encoder 
*encoder)
DRM_DEV_DEBUG(hdmi->dev, "hdmi encoder enable select: vop%s\n",
  (mux) ? "1" : "0");

-   rk3066_hdmi_setup(hdmi, &hdmi->previous_mode);
+   rk3066_hdmi_setup(hdmi, &crtc_state->adjusted_mode);
 }

-static void rk3066_hdmi_encoder_disable(struct drm_encoder *encoder)
+static void rk3066_hdmi_encoder_disable(struct drm_encoder *encoder,
+   struct drm_atomic_state *state)
 {
struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder);

@@ -449,10 +449,9 @@ rk3066_hdmi_encoder_atomic_check(struct drm_encoder 
*encoder,

 static const
 struct drm_encoder_helper_funcs rk3066_hdmi_encoder_helper_funcs = {
-   .enable   = rk3066_hdmi_encoder_enable,
-   .disable  = rk3066_hdmi_encoder_disable,
-   .mode_set = rk3066_hdmi_encoder_mode_set,
-   .atomic_check = rk3066_hdmi_encoder_atomic_check,
+   .atomic_check   = rk3066_hdmi_encoder_atomic_check,
+   .atomic_enable  = rk3066_hdmi_encoder_enable,
+   .atomic_disable = rk3066_hdmi_encoder_disable,
 };

 static enum drm_connector_status
--
2.39.2



[PATCH v1 3/4] drm/rockchip: rk3066_hdmi: Remove useless output format

2023-11-02 Thread Johan Jonker
The Rk3066 hdmi output format is hard coded to RGB. Remove
all useless code related to colorimetry and enc_out_format.

Signed-off-by: Johan Jonker 
---
 drivers/gpu/drm/rockchip/rk3066_hdmi.c | 20 +---
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c 
b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
index 0e7aae341960..f2b1b2faa096 100644
--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
@@ -23,8 +23,6 @@

 struct hdmi_data_info {
int vic; /* The CEA Video ID (VIC) of the current drm display mode. */
-   unsigned int enc_out_format;
-   unsigned int colorimetry;
 };

 struct rk3066_hdmi_i2c {
@@ -200,14 +198,7 @@ static int rk3066_hdmi_config_avi(struct rk3066_hdmi *hdmi,
rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
  &hdmi->connector, mode);

-   if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
-   frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
-   else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422)
-   frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
-   else
-   frame.avi.colorspace = HDMI_COLORSPACE_RGB;
-
-   frame.avi.colorimetry = hdmi->hdmi_data.colorimetry;
+   frame.avi.colorspace = HDMI_COLORSPACE_RGB;
frame.avi.scan_mode = HDMI_SCAN_MODE_NONE;

return rk3066_hdmi_upload_frame(hdmi, rc, &frame,
@@ -329,15 +320,6 @@ static int rk3066_hdmi_setup(struct rk3066_hdmi *hdmi,
struct drm_display_info *display = &hdmi->connector.display_info;

hdmi->hdmi_data.vic = drm_match_cea_mode(mode);
-   hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
-
-   if (hdmi->hdmi_data.vic == 6 || hdmi->hdmi_data.vic == 7 ||
-   hdmi->hdmi_data.vic == 21 || hdmi->hdmi_data.vic == 22 ||
-   hdmi->hdmi_data.vic == 2 || hdmi->hdmi_data.vic == 3 ||
-   hdmi->hdmi_data.vic == 17 || hdmi->hdmi_data.vic == 18)
-   hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
-   else
-   hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;

hdmi->tmdsclk = mode->clock * 1000;

--
2.39.2



[PATCH v1 4/4] drm/rockchip: rk3066_hdmi: Remove unused drm device pointer

2023-11-02 Thread Johan Jonker
The drm_dev field in the rk3066_hdmi struct stores a pointer to the DRM
device but is never used anywhere in the driver. Let's remove it.

Signed-off-by: Johan Jonker 
---
 drivers/gpu/drm/rockchip/rk3066_hdmi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c 
b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
index f2b1b2faa096..c51520ec58d2 100644
--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
@@ -38,7 +38,6 @@ struct rk3066_hdmi_i2c {

 struct rk3066_hdmi {
struct device *dev;
-   struct drm_device *drm_dev;
struct regmap *grf_regmap;
int irq;
struct clk *hclk;
@@ -734,7 +733,6 @@ static int rk3066_hdmi_bind(struct device *dev, struct 
device *master,
return -ENOMEM;

hdmi->dev = dev;
-   hdmi->drm_dev = drm;
hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(hdmi->regs))
return PTR_ERR(hdmi->regs);
--
2.39.2



[PATCH v2 1/3] drm/amdgpu: Don't implicit sync PRT maps.

2023-11-02 Thread Tatsuyuki Ishi
These are considered map operations rather than unmap, and there is no
point of doing implicit synchronization here.

Signed-off-by: Tatsuyuki Ishi 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index f5daadcec865..7b9762f1cddd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -902,7 +902,7 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, 
struct amdgpu_vm *vm,
/* Implicitly sync to command submissions in the same VM before
 * unmapping. Sync to moving fences before mapping.
 */
-   if (!(flags & AMDGPU_PTE_VALID))
+   if (!(flags & (AMDGPU_PTE_VALID | AMDGPU_PTE_PRT)))
sync_mode = AMDGPU_SYNC_EQ_OWNER;
else
sync_mode = AMDGPU_SYNC_EXPLICIT;
-- 
2.42.0



[PATCH v2 2/3] drm/amdgpu: Add flag to disable implicit sync for GEM operations.

2023-11-02 Thread Tatsuyuki Ishi
In Vulkan, it is the application's responsibility to perform adequate
synchronization before a sparse unmap, replace or BO destroy operation.
Until now, the kernel applied the same rule as implicitly-synchronized
APIs like OpenGL, which with per-VM BOs made page table updates stall the
queue completely. The newly added AMDGPU_VM_EXPLICIT_SYNC flag allows
drivers to opt-out of this behavior, while still ensuring adequate implicit
sync happens for kernel-initiated updates (e.g. BO moves).

We record whether to use implicit sync or not for each freed mapping. To
avoid increasing the mapping struct's size, this is union-ized with the
interval tree field which is unused after the unmap.

The reason this is done with a GEM ioctl flag, instead of being a VM /
context global setting, is that the current libdrm implementation shares
the DRM handle even between different kind of drivers (radeonsi vs radv).

Signed-off-by: Tatsuyuki Ishi 
---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   | 14 --
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h|  7 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h |  6 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c| 47 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h| 23 +
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c  | 18 +++
 include/uapi/drm/amdgpu_drm.h |  2 +
 9 files changed, 71 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 7d6daf8d2bfa..10e129bff977 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1196,7 +1196,7 @@ static void unmap_bo_from_gpuvm(struct kgd_mem *mem,
struct amdgpu_device *adev = entry->adev;
struct amdgpu_vm *vm = bo_va->base.vm;
 
-   amdgpu_vm_bo_unmap(adev, bo_va, entry->va);
+   amdgpu_vm_bo_unmap(adev, bo_va, entry->va, true);
 
amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
index 720011019741..612279e65bff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
@@ -122,7 +122,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, 
struct amdgpu_vm *vm,
}
}
 
-   r = amdgpu_vm_bo_unmap(adev, bo_va, csa_addr);
+   r = amdgpu_vm_bo_unmap(adev, bo_va, csa_addr, true);
if (r) {
DRM_ERROR("failed to do bo_unmap on static CSA, err=%d\n", r);
goto error;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index a1b15d0d6c48..cca68b89754e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -667,9 +667,9 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
const uint32_t valid_flags = AMDGPU_VM_DELAY_UPDATE |
AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE |
AMDGPU_VM_PAGE_EXECUTABLE | AMDGPU_VM_MTYPE_MASK |
-   AMDGPU_VM_PAGE_NOALLOC;
+   AMDGPU_VM_PAGE_NOALLOC | AMDGPU_VM_EXPLICIT_SYNC;
const uint32_t prt_flags = AMDGPU_VM_DELAY_UPDATE |
-   AMDGPU_VM_PAGE_PRT;
+   AMDGPU_VM_PAGE_PRT | AMDGPU_VM_EXPLICIT_SYNC;
 
struct drm_amdgpu_gem_va *args = data;
struct drm_gem_object *gobj;
@@ -680,6 +680,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
struct drm_exec exec;
uint64_t va_flags;
uint64_t vm_size;
+   bool sync_unmap;
int r = 0;
 
if (args->va_address < AMDGPU_VA_RESERVED_SIZE) {
@@ -715,6 +716,8 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
return -EINVAL;
}
 
+   sync_unmap = !(args->flags & AMDGPU_VM_EXPLICIT_SYNC);
+
switch (args->operation) {
case AMDGPU_VA_OP_MAP:
case AMDGPU_VA_OP_UNMAP:
@@ -774,19 +777,20 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void 
*data,
 va_flags);
break;
case AMDGPU_VA_OP_UNMAP:
-   r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address);
+   r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address,
+  sync_unmap);
break;
 
case AMDGPU_VA_OP_CLEAR:
r = amdgpu_vm_bo_clear_mappings(adev, &fpriv->vm,
args->va_address,
-   args->map_size);
+   args->map_size, sync_unmap);
break;
case AMDGPU_VA_OP_REPLACE:
va_flags = amdgpu_gem_va_map_flags(adev, args->flags);
 

[PATCH v2 0/3] drm/amdgpu: Add flag to disable implicit sync for GEM operations.

2023-11-02 Thread Tatsuyuki Ishi
In Vulkan, it is the application's responsibility to perform adequate
synchronization before a sparse unmap, replace or BO destroy operation.
This adds an option to AMDGPU_VA_OPs to disable redundant implicit sync
that happens on sparse unmap or replace operations.

This has seen a significant improvement in stutter in Forza Horizon 5
and Forza Horizon 4. (As games that had significant issues in sparse
binding related stutter).

Compared to the previous series [1], this specifically targets the VM
operations and keep everything else intact, including implicit sync on
kernel-initiated moves.

I've been able to pass a full Vulkan CTS run on Navi 10 with this.

Userspace code for this is available at [2] and a branch for the kernel
code is available at [3].

v2 changes:
- Drop the changes to flush split bindings eagerly as its incompatible
  with TLB flush quirks in current hardware. Drop the refactoring
  commits related to that change too.
- Fixed a missing doc warning.
- Removed an accidentally included ioctl change.

[1]: 
https://lore.kernel.org/all/20230821062005.109771-1-ishitatsuy...@gmail.com/
[2]: 
https://gitlab.freedesktop.org/ishitatsuyuki/mesa/-/commits/vm-explicit-sync
[3]: https://github.com/ishitatsuyuki/linux/tree/explicit-sync-drm-misc-next

Tatsuyuki Ishi (3):
  drm/amdgpu: Don't implicit sync PRT maps.
  drm/amdgpu: Add flag to disable implicit sync for GEM operations.
  drm/amdgpu: Bump amdgpu driver version.

 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   | 14 --
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h|  7 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h |  6 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c| 47 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h| 23 +
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c  | 18 +++
 include/uapi/drm/amdgpu_drm.h |  2 +
 10 files changed, 73 insertions(+), 51 deletions(-)

-- 
2.42.0



Re: [PATCH] gpu/drm/drm_framebuffer.c: Use Macro instead of actual number.

2023-11-02 Thread 彭昊
Good idea!
> From: "Thomas Zimmermann"
> Date:  Thu, Nov 2, 2023, 21:27
> Subject:  Re: [PATCH] gpu/drm/drm_framebuffer.c: Use Macro instead of actual 
> number.
> To: "Peng Hao", , 
> , , 
> Cc: , 
> Hi
> 
> Am 02.11.23 um 03:29 schrieb Peng Hao:
> > Use Macro DRM_FORMAT_MAX_PLANES instead of 4, to improve modifiability.
> > 
> > Signed-off-by: Peng Hao 
> > ---
> >   drivers/gpu/drm/drm_framebuffer.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_framebuffer.c 
> > b/drivers/gpu/drm/drm_framebuffer.c
> > index 2dd97473ca10..bf283dae9090 100644
> > --- a/drivers/gpu/drm/drm_framebuffer.c
> > +++ b/drivers/gpu/drm/drm_framebuffer.c
> > @@ -254,7 +254,7 @@ static int framebuffer_check(struct drm_device *dev,
> > }
> > }
> >   
> > -   for (i = info->num_planes; i < 4; i++) {
> > +   for (i = info->num_planes; i < DRM_FORMAT_MAX_PLANES; i++) {
> 
> This change makes the code more fragile. '4' is a fixed constant in the 
> UAPI struct, while DRM_FORMAT_MAX_PLANES is an internal constant. I 
> agree that both should reasonably have the same value. But (potentially) 
> changing the value of DRM_FORMAT_MAX_PLANES will break these loops with 
> a possible OOB access.
> 
> To make make this code more robust, it might be better to rewrite the 
> tests like this
> 
> for (i = num_planes; i < ARRAY_SIZE(r->modifier); +i) {
>   // the test for modifier[i]
> }
> 
> if (r->flags & DRM_MODE_FB_MODIFIERS) {
>   for (i < ARRAY_SIZE(handles)) {
>   // test for handles[i]
>   }
>   for (i < ARRAY_SIZE(pitches)) {
>   // test for pitches[i]
>   }
>   for (i < ARRAY_SIZE(offsets)) {
>   // test for offsets[i]
>   }
> }
> 
> Best regards
> Thomas
> 
> > if (r->modifier[i]) {
> > drm_dbg_kms(dev, "non-zero modifier for unused plane 
> > %d\n", i);
> > return -EINVAL;
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Frankenstrasse 146, 90461 Nuernberg, Germany
> GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
> HRB 36809 (AG Nuernberg)


[PATCH] drm/panfrost: Really power off GPU cores in panfrost_gpu_power_off()

2023-11-02 Thread AngeloGioacchino Del Regno
The layout of the registers {TILER,SHADER,L2}_PWROFF_LO, used to request
powering off cores, is the same as the {TILER,SHADER,L2}_PWRON_LO ones:
this means that in order to request poweroff of cores, we are supposed
to write a bitmask of cores that should be powered off!
This means that the panfrost_gpu_power_off() function has always been
doing nothing.

Fix powering off the GPU by writing a bitmask of the cores to poweroff
to the relevant PWROFF_LO registers and then check that the transition
(from ON to OFF) has finished by polling the relevant PWRTRANS_LO
registers.

While at it, in order to avoid code duplication, move the core mask
logic from panfrost_gpu_power_on() to a new panfrost_get_core_mask()
function, used in both poweron and poweroff.

Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver")
Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/panfrost/panfrost_gpu.c | 65 ++---
 1 file changed, 47 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c 
b/drivers/gpu/drm/panfrost/panfrost_gpu.c
index f0be7e19b13e..fad75b6e543e 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
@@ -362,28 +362,38 @@ unsigned long long panfrost_cycle_counter_read(struct 
panfrost_device *pfdev)
return ((u64)hi << 32) | lo;
 }
 
+static u64 panfrost_get_core_mask(struct panfrost_device *pfdev)
+{
+   u64 core_mask;
+
+   if (pfdev->features.l2_present == 1)
+   return U64_MAX;
+
+   /*
+* Only support one core group now.
+* ~(l2_present - 1) unsets all bits in l2_present except
+* the bottom bit. (l2_present - 2) has all the bits in
+* the first core group set. AND them together to generate
+* a mask of cores in the first core group.
+*/
+   core_mask = ~(pfdev->features.l2_present - 1) &
+(pfdev->features.l2_present - 2);
+   dev_info_once(pfdev->dev, "using only 1st core group (%lu cores from 
%lu)\n",
+ hweight64(core_mask),
+ hweight64(pfdev->features.shader_present));
+
+   return core_mask;
+}
+
 void panfrost_gpu_power_on(struct panfrost_device *pfdev)
 {
int ret;
u32 val;
-   u64 core_mask = U64_MAX;
+   u64 core_mask;
 
panfrost_gpu_init_quirks(pfdev);
+   core_mask = panfrost_get_core_mask(pfdev);
 
-   if (pfdev->features.l2_present != 1) {
-   /*
-* Only support one core group now.
-* ~(l2_present - 1) unsets all bits in l2_present except
-* the bottom bit. (l2_present - 2) has all the bits in
-* the first core group set. AND them together to generate
-* a mask of cores in the first core group.
-*/
-   core_mask = ~(pfdev->features.l2_present - 1) &
-(pfdev->features.l2_present - 2);
-   dev_info_once(pfdev->dev, "using only 1st core group (%lu cores 
from %lu)\n",
- hweight64(core_mask),
- hweight64(pfdev->features.shader_present));
-   }
gpu_write(pfdev, L2_PWRON_LO, pfdev->features.l2_present & core_mask);
ret = readl_relaxed_poll_timeout(pfdev->iomem + L2_READY_LO,
val, val == (pfdev->features.l2_present & core_mask),
@@ -408,11 +418,30 @@ void panfrost_gpu_power_on(struct panfrost_device *pfdev)
 
 void panfrost_gpu_power_off(struct panfrost_device *pfdev)
 {
-   gpu_write(pfdev, TILER_PWROFF_LO, 0);
-   gpu_write(pfdev, SHADER_PWROFF_LO, 0);
-   gpu_write(pfdev, L2_PWROFF_LO, 0);
+   u64 core_mask = panfrost_get_core_mask(pfdev);
+   int ret;
+   u32 val;
+
+   gpu_write(pfdev, SHADER_PWROFF_LO, pfdev->features.shader_present & 
core_mask);
+   ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_PWRTRANS_LO,
+val, !val, 1, 1000);
+   if (ret)
+   dev_err(pfdev->dev, "shader power transition timeout");
+
+   gpu_write(pfdev, TILER_PWROFF_LO, pfdev->features.tiler_present);
+   ret = readl_relaxed_poll_timeout(pfdev->iomem + TILER_PWRTRANS_LO,
+val, !val, 1, 1000);
+   if (ret)
+   dev_err(pfdev->dev, "tiler power transition timeout");
+
+   gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present & core_mask);
+   ret = readl_poll_timeout(pfdev->iomem + L2_PWRTRANS_LO,
+val, !val, 0, 1000);
+   if (ret)
+   dev_err(pfdev->dev, "l2 power transition timeout");
 }
 
+
 int panfrost_gpu_init(struct panfrost_device *pfdev)
 {
int err, irq;
-- 
2.42.0



Re: [PATCH v2 6/7] drm/i915/dsi: Replace poking of CHV GPIOs behind the driver's back

2023-11-02 Thread Andy Shevchenko
On Wed, Nov 01, 2023 at 11:20:23AM +0100, Hans de Goede wrote:
> On 11/1/23 10:32, Andy Shevchenko wrote:
> > On Tue, Oct 31, 2023 at 10:15:52PM +0100, Hans de Goede wrote:
> >> On 10/31/23 17:07, Hans de Goede wrote:
> >>> On 10/24/23 18:11, Andy Shevchenko wrote:
>  On Tue, Oct 24, 2023 at 06:57:38PM +0300, Andy Shevchenko wrote:

...

> Note you still need the first part of my patch which is
> an unrelated bugfix:
> 
> --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
> +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
> @@ -219,8 +219,7 @@ static void soc_exec_gpio(struct intel_connector 
> *connector, const char *con_id,
>   } else {
>   gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev,
>con_id, gpio_index,
> -  value ? GPIOD_OUT_LOW :
> -  GPIOD_OUT_HIGH);
> +  value ? GPIOD_OUT_HIGH : 
> GPIOD_OUT_LOW);
>   if (IS_ERR(gpio_desc)) {
>   drm_err(&dev_priv->drm,
>   "GPIO index %u request failed (%pe)\n",

Can you attach or send a formal submission, so I can incorporate it into one
(v3) series among other changes?

-- 
With Best Regards,
Andy Shevchenko




[PATCH v2 3/3] drm/amdgpu: Bump amdgpu driver version.

2023-11-02 Thread Tatsuyuki Ishi
For detection of the new explicit sync functionality without having to try
the ioctl.

Signed-off-by: Tatsuyuki Ishi 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 81edf66dbea8..2aa406dee192 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -113,9 +113,10 @@
  *gl1c_cache_size, gl2c_cache_size, mall_size, 
enabled_rb_pipes_mask_hi
  *   3.53.0 - Support for GFX11 CP GFX shadowing
  *   3.54.0 - Add AMDGPU_CTX_QUERY2_FLAGS_RESET_IN_PROGRESS support
+ * - 3.55.0 - Add AMDGPU_VM_EXPLICIT_SYNC flag for GEM operations.
  */
 #define KMS_DRIVER_MAJOR   3
-#define KMS_DRIVER_MINOR   54
+#define KMS_DRIVER_MINOR   55
 #define KMS_DRIVER_PATCHLEVEL  0
 
 unsigned int amdgpu_vram_limit = UINT_MAX;
-- 
2.42.0



[PATCH v2 0/6] drm/panfrost: Turn off clocks and regulators in PM

2023-11-02 Thread AngeloGioacchino Del Regno
Changes in v2:
 - Added hard reset GPU recovery
 - Tightened polling time for soft reset and power on
 - New execution time measurements after poweroff fix (see [1])

[1]: 
https://lore.kernel.org/all/20231102141507.73481-1-angelogioacchino.delre...@collabora.com/

At least MediaTek platforms are able to get the GPU clocks and regulators
completely off during system suspend, allowing to save a bit of power.

Panfrost is used on more than just MediaTek SoCs and the benefits of this
can be variable across different SoC models and/or different SoCs from
different manufacturers: this means that just adding this ability for all
could result in unexpected issues and breakages on untested SoCs.

For the aforemenetioned reasons, turning off the clocks and/or regulators
was implemented inside of a capabilities barrier that shall be enabled on
a per-SoC basis (in the panfrost_compatible platform data) after testing
of both benefits and feasibility.

In this series, I am adding the ability to switch on/off clocks and
regulators and enabling that on all MediaTek platforms, as I was able
to successfully test that on multiple Chromebooks featuring different
MediaTek SoCs; specifically, I've manually tested on MT8186, MT8192 and
MT8195, while MT8183 got tested only by KernelCI.

Cheers!

AngeloGioacchino Del Regno (6):
  drm/panfrost: Perform hard reset to recover GPU if soft reset fails
  drm/panfrost: Tighten polling for soft reset and power on
  drm/panfrost: Implement ability to turn on/off GPU clocks in suspend
  drm/panfrost: Set clocks on/off during system sleep on MediaTek SoCs
  drm/panfrost: Implement ability to turn on/off regulators in suspend
  drm/panfrost: Set regulators on/off during system sleep on MediaTek
SoCs

 drivers/gpu/drm/panfrost/panfrost_device.c | 78 --
 drivers/gpu/drm/panfrost/panfrost_device.h | 13 
 drivers/gpu/drm/panfrost/panfrost_drv.c|  3 +
 drivers/gpu/drm/panfrost/panfrost_gpu.c| 22 +++---
 drivers/gpu/drm/panfrost/panfrost_regs.h   |  1 +
 5 files changed, 105 insertions(+), 12 deletions(-)

-- 
2.42.0



[PATCH v2 5/6] drm/panfrost: Implement ability to turn on/off regulators in suspend

2023-11-02 Thread AngeloGioacchino Del Regno
Some platforms/SoCs can power off the GPU entirely by completely cutting
off power, greatly enhancing battery time during system suspend: add a
new pm_feature GPU_PM_VREG_OFF to allow turning off the GPU regulators
during full suspend only on selected platforms.

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/panfrost/panfrost_device.c | 19 ++-
 drivers/gpu/drm/panfrost/panfrost_device.h |  2 ++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c 
b/drivers/gpu/drm/panfrost/panfrost_device.c
index 2022ed76a620..51b22eb0971d 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -431,10 +431,21 @@ static int panfrost_device_resume(struct device *dev)
struct panfrost_device *pfdev = dev_get_drvdata(dev);
int ret;
 
+   if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) {
+   unsigned long freq = pfdev->pfdevfreq.fast_rate;
+   struct dev_pm_opp *opp;
+
+   opp = dev_pm_opp_find_freq_ceil(dev, &freq);
+   if (IS_ERR(opp))
+   return PTR_ERR(opp);
+   dev_pm_opp_put(opp);
+   dev_pm_opp_set_opp(dev, opp);
+   }
+
if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) {
ret = clk_enable(pfdev->clock);
if (ret)
-   return ret;
+   goto err_clk;
 
if (pfdev->bus_clock) {
ret = clk_enable(pfdev->bus_clock);
@@ -455,6 +466,9 @@ static int panfrost_device_resume(struct device *dev)
 err_bus_clk:
if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS))
clk_disable(pfdev->clock);
+err_clk:
+   if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF))
+   dev_pm_opp_set_opp(dev, NULL);
return ret;
 }
 
@@ -474,6 +488,9 @@ static int panfrost_device_suspend(struct device *dev)
clk_disable(pfdev->bus_clock);
}
 
+   if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF))
+   dev_pm_opp_set_opp(dev, NULL);
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index d7f179eb8ea3..0fc558db6bfd 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -28,9 +28,11 @@ struct panfrost_perfcnt;
 /**
  * enum panfrost_gpu_pm - Supported kernel power management features
  * @GPU_PM_CLK_DIS:  Allow disabling clocks during system suspend
+ * @GPU_PM_VREG_OFF: Allow turning off regulators during system suspend
  */
 enum panfrost_gpu_pm {
GPU_PM_CLK_DIS,
+   GPU_PM_VREG_OFF,
 };
 
 struct panfrost_features {
-- 
2.42.0



[PATCH v2 6/6] drm/panfrost: Set regulators on/off during system sleep on MediaTek SoCs

2023-11-02 Thread AngeloGioacchino Del Regno
All of the MediaTek SoCs supported by Panfrost can completely cut power
to the GPU during full system sleep without any user-noticeable delay
in the resume operation, as shown by measurements taken on multiple
MediaTek SoCs.

As an example, for MT8195 - a "before" with only runtime PM operations
(so, without turning on/off regulators), and an "after" executing both
the system sleep .resume() handler and .runtime_resume() (so the time
refers to T_Resume + T_Runtime_Resume):

Average Panfrost-only system sleep resume time, before: ~33500ns
Average Panfrost-only system sleep resume time, after:  ~336200ns

Keep in mind that this additional ~308200 nanoseconds delay happens only
in resume from a full system suspend, and not in runtime PM operations,
hence it is acceptable.

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/panfrost/panfrost_drv.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 82f3c5fe9c58..f63382d9ab04 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -734,7 +734,7 @@ static const struct panfrost_compatible 
mediatek_mt8183_b_data = {
.supply_names = mediatek_mt8183_b_supplies,
.num_pm_domains = ARRAY_SIZE(mediatek_mt8183_pm_domains),
.pm_domain_names = mediatek_mt8183_pm_domains,
-   .pm_features = BIT(GPU_PM_CLK_DIS),
+   .pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF),
 };
 
 static const char * const mediatek_mt8186_pm_domains[] = { "core0", "core1" };
@@ -743,7 +743,7 @@ static const struct panfrost_compatible 
mediatek_mt8186_data = {
.supply_names = mediatek_mt8183_b_supplies,
.num_pm_domains = ARRAY_SIZE(mediatek_mt8186_pm_domains),
.pm_domain_names = mediatek_mt8186_pm_domains,
-   .pm_features = BIT(GPU_PM_CLK_DIS),
+   .pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF),
 };
 
 static const char * const mediatek_mt8192_supplies[] = { "mali", NULL };
@@ -754,7 +754,7 @@ static const struct panfrost_compatible 
mediatek_mt8192_data = {
.supply_names = mediatek_mt8192_supplies,
.num_pm_domains = ARRAY_SIZE(mediatek_mt8192_pm_domains),
.pm_domain_names = mediatek_mt8192_pm_domains,
-   .pm_features = BIT(GPU_PM_CLK_DIS),
+   .pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF),
 };
 
 static const struct of_device_id dt_match[] = {
-- 
2.42.0



[PATCH v2 2/6] drm/panfrost: Tighten polling for soft reset and power on

2023-11-02 Thread AngeloGioacchino Del Regno
In many cases, soft reset takes more than 1 microsecond, but definitely
less than 10; moreover in the poweron flow, tilers, shaders and l2 will
become ready (each) in less than 10 microseconds as well.

Even in the cases (at least on my platforms, rarely) in which those take
more than 10 microseconds, it's very unlikely to see both soft reset and
poweron to take more than 70 microseconds.

Shorten the polling delay to 10 microseconds to consistently reduce the
runtime resume time of the GPU.

As an indicative example, measurements taken on a MediaTek MT8195 SoC

Average runtime resume time in nanoseconds before this commit:
GDM, user selection up/down:88435ns
GDM, Text Entry (typing user/password): 91489ns
GNOME Desktop, idling, GKRELLM running: 73200ns

After this commit:

GDM: user selection up/down:26690ns
GDM: Text Entry (typing user/password): 27917ns
GNOME Desktop, idling, GKRELLM running: 25304ns

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/panfrost/panfrost_gpu.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c 
b/drivers/gpu/drm/panfrost/panfrost_gpu.c
index 7e9e2cf26e4d..e264e8c2252d 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
@@ -63,7 +63,7 @@ int panfrost_gpu_soft_reset(struct panfrost_device *pfdev)
 
gpu_write(pfdev, GPU_CMD, GPU_CMD_SOFT_RESET);
ret = readl_relaxed_poll_timeout(pfdev->iomem + GPU_INT_RAWSTAT,
-   val, val & GPU_IRQ_RESET_COMPLETED, 100, 1);
+   val, val & GPU_IRQ_RESET_COMPLETED, 10, 1);
if (ret) {
dev_err(pfdev->dev, "gpu soft reset timed out, attempting hard 
reset\n");
 
@@ -403,7 +403,7 @@ void panfrost_gpu_power_on(struct panfrost_device *pfdev)
gpu_write(pfdev, L2_PWRON_LO, pfdev->features.l2_present & core_mask);
ret = readl_relaxed_poll_timeout(pfdev->iomem + L2_READY_LO,
val, val == (pfdev->features.l2_present & core_mask),
-   100, 2);
+   10, 2);
if (ret)
dev_err(pfdev->dev, "error powering up gpu L2");
 
@@ -411,13 +411,13 @@ void panfrost_gpu_power_on(struct panfrost_device *pfdev)
  pfdev->features.shader_present & core_mask);
ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_READY_LO,
val, val == (pfdev->features.shader_present & core_mask),
-   100, 2);
+   10, 2);
if (ret)
dev_err(pfdev->dev, "error powering up gpu shader");
 
gpu_write(pfdev, TILER_PWRON_LO, pfdev->features.tiler_present);
ret = readl_relaxed_poll_timeout(pfdev->iomem + TILER_READY_LO,
-   val, val == pfdev->features.tiler_present, 100, 1000);
+   val, val == pfdev->features.tiler_present, 10, 1000);
if (ret)
dev_err(pfdev->dev, "error powering up gpu tiler");
 }
-- 
2.42.0



Re: [PATCH v2 6/7] drm/i915/dsi: Replace poking of CHV GPIOs behind the driver's back

2023-11-02 Thread Hans de Goede
Hi,

On 11/2/23 15:19, Andy Shevchenko wrote:
> On Wed, Nov 01, 2023 at 11:20:23AM +0100, Hans de Goede wrote:
>> On 11/1/23 10:32, Andy Shevchenko wrote:
>>> On Tue, Oct 31, 2023 at 10:15:52PM +0100, Hans de Goede wrote:
 On 10/31/23 17:07, Hans de Goede wrote:
> On 10/24/23 18:11, Andy Shevchenko wrote:
>> On Tue, Oct 24, 2023 at 06:57:38PM +0300, Andy Shevchenko wrote:
> 
> ...
> 
>> Note you still need the first part of my patch which is
>> an unrelated bugfix:
>>
>> --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
>> @@ -219,8 +219,7 @@ static void soc_exec_gpio(struct intel_connector 
>> *connector, const char *con_id,
>>  } else {
>>  gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev,
>>   con_id, gpio_index,
>> - value ? GPIOD_OUT_LOW :
>> - GPIOD_OUT_HIGH);
>> + value ? GPIOD_OUT_HIGH : 
>> GPIOD_OUT_LOW);
>>  if (IS_ERR(gpio_desc)) {
>>  drm_err(&dev_priv->drm,
>>  "GPIO index %u request failed (%pe)\n",
> 
> Can you attach or send a formal submission, so I can incorporate it into one
> (v3) series among other changes?

I thought this fixed new code in your series and it is a trivial fix,
so my idea was that you would just fold the fix into the patch
introducing the code.

But I see now that this is existing code from bxt_exec_gpio().

A formal fix to use as a prep patch for your series is now attached,
this is based on top of drm-misc-next (I guess drm-intel-next
would be better but I had an up2date drm-misc-next handy).

Regards,

Hans

From c300ed0e09d1fd14bf966dc172c6db54b888faf3 Mon Sep 17 00:00:00 2001
From: Hans de Goede 
Date: Wed, 1 Nov 2023 11:49:01 +0100
Subject: [PATCH] drm/i915/dsi: Fix wrong initial value for GPIOs in
 bxt_exec_gpio()

Fix wrong initial value for GPIOs in bxt_exec_gpio().

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index e56ec3f2d84a..0587cbc2e584 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -356,9 +356,7 @@ static void bxt_exec_gpio(struct intel_connector *connector,
 	if (!gpio_desc) {
 		gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev,
 		 NULL, gpio_index,
-		 value ? GPIOD_OUT_LOW :
-		 GPIOD_OUT_HIGH);
-
+		 value ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW);
 		if (IS_ERR_OR_NULL(gpio_desc)) {
 			drm_err(&dev_priv->drm,
 "GPIO index %u request failed (%ld)\n",
-- 
2.41.0



[PATCH v2 1/6] drm/panfrost: Perform hard reset to recover GPU if soft reset fails

2023-11-02 Thread AngeloGioacchino Del Regno
Even though soft reset should ideally never fail, during development of
some power management features I managed to get some bits wrong: this
resulted in GPU soft reset failures, where the GPU was never able to
recover, not even after suspend/resume cycles, meaning that the only
way to get functionality back was to reboot the machine.

Perform a hard reset after a soft reset failure to be able to recover
the GPU during runtime (so, without any machine reboot).

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/panfrost/panfrost_gpu.c  | 14 ++
 drivers/gpu/drm/panfrost/panfrost_regs.h |  1 +
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c 
b/drivers/gpu/drm/panfrost/panfrost_gpu.c
index fad75b6e543e..7e9e2cf26e4d 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
@@ -60,14 +60,20 @@ int panfrost_gpu_soft_reset(struct panfrost_device *pfdev)
 
gpu_write(pfdev, GPU_INT_MASK, 0);
gpu_write(pfdev, GPU_INT_CLEAR, GPU_IRQ_RESET_COMPLETED);
-   gpu_write(pfdev, GPU_CMD, GPU_CMD_SOFT_RESET);
 
+   gpu_write(pfdev, GPU_CMD, GPU_CMD_SOFT_RESET);
ret = readl_relaxed_poll_timeout(pfdev->iomem + GPU_INT_RAWSTAT,
val, val & GPU_IRQ_RESET_COMPLETED, 100, 1);
-
if (ret) {
-   dev_err(pfdev->dev, "gpu soft reset timed out\n");
-   return ret;
+   dev_err(pfdev->dev, "gpu soft reset timed out, attempting hard 
reset\n");
+
+   gpu_write(pfdev, GPU_CMD, GPU_CMD_HARD_RESET);
+   ret = readl_relaxed_poll_timeout(pfdev->iomem + GPU_INT_RAWSTAT,
+   val, val & GPU_IRQ_RESET_COMPLETED, 100, 1);
+   if (ret) {
+   dev_err(pfdev->dev, "gpu hard reset timed out\n");
+   return ret;
+   }
}
 
gpu_write(pfdev, GPU_INT_CLEAR, GPU_IRQ_MASK_ALL);
diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h 
b/drivers/gpu/drm/panfrost/panfrost_regs.h
index 55ec807550b3..c25743b05c55 100644
--- a/drivers/gpu/drm/panfrost/panfrost_regs.h
+++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
@@ -44,6 +44,7 @@
 GPU_IRQ_MULTIPLE_FAULT)
 #define GPU_CMD0x30
 #define   GPU_CMD_SOFT_RESET   0x01
+#define   GPU_CMD_HARD_RESET   0x02
 #define   GPU_CMD_PERFCNT_CLEAR0x03
 #define   GPU_CMD_PERFCNT_SAMPLE   0x04
 #define   GPU_CMD_CYCLE_COUNT_START0x05
-- 
2.42.0



Re: [PATCH 3/3] drm/panel-edp: Choose correct preferred mode

2023-11-02 Thread Doug Anderson
Hi,

On Wed, Nov 1, 2023 at 11:31 PM Dmitry Baryshkov
 wrote:
>
> On Wed, 1 Nov 2023 at 23:26, Hsin-Yi Wang  wrote:
> >
> > If a non generic edp-panel is under aux-bus, the mode read from edid would
> > still be selected as preferred and results in multiple preferred modes,
> > which is ambiguous.
> >
> > If a hard-coded mode is present, unset the preferred bit of the modes read
> > from edid.
>
> Can we skip the EDID completely if the hardcoded override is present?

Yeah, I wondered about that too. The blending of the hardcoded with
the EDID predates my involvement with the driver. You can see even as
of commit 280921de7241 ("drm/panel: Add simple panel support") that
the driver would start with the EDID modes (if it had them) and then
go onto add the hardcoded modes. At least for eDP panels, though,
nobody (or almost nobody?) actually provided panel-simple a DDC bus at
the same time it was given a hardcoded panel.

I guess I could go either way, but I have a slight bias to adding the
extra modes and just making it clear to userspace that none of them
are "preferred". That seems like it would give userspace the most
flexibility and also is closer to what we've historically done
(though, historically, we just allowed there to be more than one
"preferred" mode).

One thing we definitely want to do, though, is to still expose the
EDID to userspace even if we're using a hardcoded mode. I believe
that, at least on ChromeOS, there are some tools that look at the EDID
directly for some reason or another.


> > Signed-off-by: Hsin-Yi Wang 
> > ---
> >  drivers/gpu/drm/drm_modes.c   | 16 
> >  drivers/gpu/drm/panel/panel-edp.c |  7 +--
> >  include/drm/drm_modes.h   |  1 +
> >  3 files changed, 22 insertions(+), 2 deletions(-)
>
> Anyway, this should be split into two patches. One for drm_modes.c,
> another one for the panel driver.

Yeah, that's probably a good idea.

-Doug


[PATCH v2 4/6] drm/panfrost: Set clocks on/off during system sleep on MediaTek SoCs

2023-11-02 Thread AngeloGioacchino Del Regno
All of the MediaTek SoCs supported by Panfrost can switch the clocks
off and on during system sleep to save some power without any user
experience penalty.

Measurements taken on multiple MediaTek SoCs show that adding this
will not prolong the time that is required to resume the system in
any meaningful way.

As an example, for MT8195 - a "before" with only runtime PM operations
(so, without turning on/off GPU clocks), and an "after" executing both
the system sleep .resume() handler and .runtime_resume() (so the time
refers to T_Resume + T_Runtime_Resume):

Average Panfrost-only system sleep resume time, before: ~28000ns
Average Panfrost-only system sleep resume time, after:  ~33500ns

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/panfrost/panfrost_drv.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 7cabf4e3d1f2..82f3c5fe9c58 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -734,6 +734,7 @@ static const struct panfrost_compatible 
mediatek_mt8183_b_data = {
.supply_names = mediatek_mt8183_b_supplies,
.num_pm_domains = ARRAY_SIZE(mediatek_mt8183_pm_domains),
.pm_domain_names = mediatek_mt8183_pm_domains,
+   .pm_features = BIT(GPU_PM_CLK_DIS),
 };
 
 static const char * const mediatek_mt8186_pm_domains[] = { "core0", "core1" };
@@ -742,6 +743,7 @@ static const struct panfrost_compatible 
mediatek_mt8186_data = {
.supply_names = mediatek_mt8183_b_supplies,
.num_pm_domains = ARRAY_SIZE(mediatek_mt8186_pm_domains),
.pm_domain_names = mediatek_mt8186_pm_domains,
+   .pm_features = BIT(GPU_PM_CLK_DIS),
 };
 
 static const char * const mediatek_mt8192_supplies[] = { "mali", NULL };
@@ -752,6 +754,7 @@ static const struct panfrost_compatible 
mediatek_mt8192_data = {
.supply_names = mediatek_mt8192_supplies,
.num_pm_domains = ARRAY_SIZE(mediatek_mt8192_pm_domains),
.pm_domain_names = mediatek_mt8192_pm_domains,
+   .pm_features = BIT(GPU_PM_CLK_DIS),
 };
 
 static const struct of_device_id dt_match[] = {
-- 
2.42.0



[PATCH v2 3/6] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend

2023-11-02 Thread AngeloGioacchino Del Regno
Currently, the GPU is being internally powered off for runtime suspend
and turned back on for runtime resume through commands sent to it, but
note that the GPU doesn't need to be clocked during the poweroff state,
hence it is possible to save some power on selected platforms.

Add suspend and resume handlers for full system sleep and then add
a new panfrost_gpu_pm enumeration and a pm_features variable in the
panfrost_compatible structure: BIT(GPU_PM_CLK_DIS) will be used to
enable this power saving technique only on SoCs that are able to
safely use it.

Note that this was implemented only for the system sleep case and not
for runtime PM because testing on one of my MediaTek platforms showed
issues when turning on and off clocks aggressively (in PM runtime)
resulting in a full system lockup.

Doing this only for full system sleep never showed issues during my
testing by suspending and resuming the system continuously for more
than 100 cycles.

Signed-off-by: AngeloGioacchino Del Regno 

---

Note: Even after fixing the panfrost_power_off() function, I'm still
getting issues with turning off the clocks at .runtime_suspend() but
this time, instead of getting a GPU lockup, the entire SoC will deadlock
bringing down the entire system with it (so it's even worst!) :-)


 drivers/gpu/drm/panfrost/panfrost_device.c | 61 --
 drivers/gpu/drm/panfrost/panfrost_device.h | 11 
 2 files changed, 68 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c 
b/drivers/gpu/drm/panfrost/panfrost_device.c
index 28f7046e1b1a..2022ed76a620 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -403,7 +403,7 @@ void panfrost_device_reset(struct panfrost_device *pfdev)
panfrost_job_enable_interrupts(pfdev);
 }
 
-static int panfrost_device_resume(struct device *dev)
+static int panfrost_device_runtime_resume(struct device *dev)
 {
struct panfrost_device *pfdev = dev_get_drvdata(dev);
 
@@ -413,7 +413,7 @@ static int panfrost_device_resume(struct device *dev)
return 0;
 }
 
-static int panfrost_device_suspend(struct device *dev)
+static int panfrost_device_runtime_suspend(struct device *dev)
 {
struct panfrost_device *pfdev = dev_get_drvdata(dev);
 
@@ -426,5 +426,58 @@ static int panfrost_device_suspend(struct device *dev)
return 0;
 }
 
-EXPORT_GPL_RUNTIME_DEV_PM_OPS(panfrost_pm_ops, panfrost_device_suspend,
- panfrost_device_resume, NULL);
+static int panfrost_device_resume(struct device *dev)
+{
+   struct panfrost_device *pfdev = dev_get_drvdata(dev);
+   int ret;
+
+   if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) {
+   ret = clk_enable(pfdev->clock);
+   if (ret)
+   return ret;
+
+   if (pfdev->bus_clock) {
+   ret = clk_enable(pfdev->bus_clock);
+   if (ret)
+   goto err_bus_clk;
+   }
+   }
+
+   ret = pm_runtime_force_resume(dev);
+   if (ret)
+   goto err_resume;
+
+   return 0;
+
+err_resume:
+   if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS) && pfdev->bus_clock)
+   clk_disable(pfdev->bus_clock);
+err_bus_clk:
+   if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS))
+   clk_disable(pfdev->clock);
+   return ret;
+}
+
+static int panfrost_device_suspend(struct device *dev)
+{
+   struct panfrost_device *pfdev = dev_get_drvdata(dev);
+   int ret;
+
+   ret = pm_runtime_force_suspend(dev);
+   if (ret)
+   return ret;
+
+   if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) {
+   clk_disable(pfdev->clock);
+
+   if (pfdev->bus_clock)
+   clk_disable(pfdev->bus_clock);
+   }
+
+   return 0;
+}
+
+EXPORT_GPL_DEV_PM_OPS(panfrost_pm_ops) = {
+   RUNTIME_PM_OPS(panfrost_device_runtime_suspend, 
panfrost_device_runtime_resume, NULL)
+   SYSTEM_SLEEP_PM_OPS(panfrost_device_suspend, panfrost_device_resume)
+};
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index 1ef38f60d5dc..d7f179eb8ea3 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -25,6 +25,14 @@ struct panfrost_perfcnt;
 #define NUM_JOB_SLOTS 3
 #define MAX_PM_DOMAINS 5
 
+/**
+ * enum panfrost_gpu_pm - Supported kernel power management features
+ * @GPU_PM_CLK_DIS:  Allow disabling clocks during system suspend
+ */
+enum panfrost_gpu_pm {
+   GPU_PM_CLK_DIS,
+};
+
 struct panfrost_features {
u16 id;
u16 revision;
@@ -75,6 +83,9 @@ struct panfrost_compatible {
 
/* Vendor implementation quirks callback */
void (*vendor_quirk)(struct panfrost_device *pfdev);
+
+   /* Allowed PM features */
+   u8 pm_features;
 };
 
 struct panfrost_devi

Re: [PATCH 07/10] drm/tidss: Fix dss reset

2023-11-02 Thread Francesco Dolcini
On Wed, Nov 01, 2023 at 11:17:44AM +0200, Tomi Valkeinen wrote:
> The probe function calls dispc_softreset() before runtime PM is enabled
> and without enabling any of the DSS clocks. This happens to work by
> luck, and we need to make sure the DSS HW is active and the fclk is
> enabled.

Not sure on the exact implication here, however from the description
this seems a candidate for stable and would need a Fixes tag.

Francesco



Fbdev issue after the drm updates 'drm-next-2023-10-31-1'

2023-11-02 Thread Christian Zigotzky

Hello,

There is a fbdev issue with the virtio-gpu-pci and virtio-vga. (The 
penguins are not displayed at boot time)


Error message:  [    0.889302] virtio-pci :00:02.0: [drm] *ERROR* 
fbdev: Failed to setup generic emulation (ret=-2)


The kernel 6.6 final doesn't have this issue.

Please check the fbdev changes in the drm updates 'drm-next-2023-10-31-1'.

Thanks,
Christian


[PATCH v12 0/4] Add RZ/{G2L,G2LC} and RZ/V2L Display Unit support

2023-11-02 Thread Biju Das
This path series aims to add support for RZ/G2L DU DRM driver.

RZ/G2L LCD controller composed of Frame compression Processor(FCPVD), Video
signal processor (VSPD) and Display unit(DU). The output of LCDC is
connected to Display parallel interface and MIPI link video interface.
 
The output from DSI is connected to ADV7535.

Ref:
 
https://lore.kernel.org/linux-renesas-soc/os0pr01mb5922717e4ccfe07f3c25fbc986...@os0pr01mb5922.jpnprd01.prod.outlook.com/#t

This patch series is tested with [2]
[2] https://patchwork.kernel.org/project/linux-renesas-soc/list/?series=742810

Test logs kmscube: [3]

v11->v12:
 * Dropped quotes in ref handle for renesas,vsps property.
 * Retained tags as it is trivial change.
 * Replaced rzg2l_du_write()->writel().
v10->v11:
* Replaced CONFIG_DRM_RCAR_VSP->CONFIG_VIDEO_RENESAS_VSP1 for building
  rzg2l_du_vsp driver.
* Dropped "rzg2l_du_regs.h" instead the relevant definitions defined in
  .c file.
* Dropped setting ditr5 based on latest HW manual 1.3.0/1.4.0
* Updated the comment for auto clear.
* Replaced writel()->rzg2l_du_write() in rzg2l_du_start_stop().
* Dropped CRC related functions as it does not have DISCOM.
* Replaced the variable possible_crtcs->possible_outputs in
  struct rzg2l_du_output_routing.
* Updated DMA_BIT_MASK from 40->32.
* Dropped unneeded struct drm_bridge from rzg2l_du_drv.h.
* Dropped colour keying support as it doesn't have planes.
* Added only RGB formats in rzg2l_du_format_infos.
* Dropped chroma planes from rzg2l_du_fb_create().
* Updated the comment for max_pitch in rzg2l_du_fb_create().
* Dropped possible_crtcs check in rzg2l_du_encoders_init().
* Dropped additional empty line from struct rzg2l_du_device.
v9->v10:
 * patch#1 is mainlined, so dropped from this series.
 * Added Rb tag from Laurent for the binding patch.
 * Updated the commit description.
 * Updated description of the port by dropping the text "specified in
   Documentation/devicetree/bindings/graph.txt."
 * Dropped empty endpoint from example.
 * Dropped ARM64 dependency from Kconfig.
 * Sorted the configs alphabetically in Kconfig.
 * Dropped DRM_RCAR_VSP config option and make DRM_RZG2L_DU depend on
   VIDEO_RENESAS_VSP1.
 * On rzg2l_du_crtc_set_display_timing() replaced the setting of parent
   clk rate with dclk rate.
 * Added rzg2l_du_write() wrapper function.
 * Updated the comment atomic_begin->atomic_flush.
 * Dropped .atomic_check and .atomic_begin callback
 * Renamed __rzg2l_du_crtc_plane_atomic_check->__rzg2l_du_vsp_plane_atomic
   _check and moved it to rzg2l_du_vsp.c
 * Added struct clk in rzg2l_du_crtc.h
 * Dropped the variables mmio_offset,index,vblank_lock,vblank_wait,
   vblank_count from struct rzg2l_du_crtc.
 * Replaced the macro to_rzg2l_crtc with static inline functions.
 * Dropped the unneeded header files clk.h, io.h, mm.h, pm.h, slab.h,
   wait.h and drm_managed.h from rzg2l_du_drv.c.
 * Replaced DRM_INFO->drm_info
 * Dropped the callbacks prime_handle_to_fd, prime_fd_to_handle and
   gem_prime_mmap.
 * Replaced the callback remove->remove_new.
 * Dropped header file wait.h and added forward declarations struct clk and
   rzg2l_du_device from rzg2l_du_drv.h.
 * Dropped the dsi and dpad0_source variables from struct rzg2l_du_device.
 * Replaced the macro to_rzg2l_encoder with static inline functions.
 * Dropped header files dma-buf.h and wait.h from rzg2l_du_kms.c.
 * Dropped struct sg_table and added the scatterlist.h header file in
   rzg2l_du_vsp.h
 * Added container_of.h header file, forward declarations struct device and
   struct rzg2l_du_device in rzg2l_du_vsp.h.
v8->v9:
 * Added Rb tag from Laurent and Acked-by tag from Kieran for patch#1.
 * Added Rb tag from Laurent and Geert for patch#3.
 * Dropped reset_control_assert() from error patch for rzg2l_du_crtc_get() as
   suggested by Philipp Zabel.
 * Added Rb tag from Laurent oatch#5.
 * Updated MAINTAINERS entries for common parts(Makefile and Kconfig).
v7->v8:
 * Moved rcar-du and shmobile DRM drivers to renesas specific vendor directory.
 * Fixed the typo vsp2->du in RZ/V2L DU bindings patch.
 * Added Rb tag from Rob for RZ/V2L DU bindings patch.
 * Dropped RCar du lib and created RZ/G2L DU DRM driver by creating rz_du 
folder.
 * Updated MAINTAINERS entries.
v6->v7:
 * Split DU lib and  RZ/G2L du driver as separate patch series as
   DU support added to more platforms based on RZ/G2L alike SoCs.
 * Rebased to latest drm-tip.
 * Added patch #2 for binding support for RZ/V2L DU
 * Added patch #4 for driver support for RZ/V2L DU
 * Added patch #5 for SoC DTSI support for RZ/G2L DU
 * Added patch #6 for SoC DTSI support for RZ/V2L DU
 * Added patch #7 for Enabling DU on SMARC EVK based on RZ/{G2L,V2L} SoCs.
 * Added patch #8 for Enabling DU on SMARC EVK based on RZ/G2LC SoC.
v5->v6:
 * Merged DU lib and RZ/G2L du driver in same patch series
 * Rebased to latest drm-misc.
 * Merged patch#1 to RZ/G2L Driver patch.
 * Updated KConfig dependency from ARCH_RENESAS->ARCH_RZG2L.
 * Optimized rzg2l_du_output_n

[PATCH v12 3/4] drm: renesas: Add RZ/G2L DU Support

2023-11-02 Thread Biju Das
The LCD controller is composed of Frame Compression Processor (FCPVD),
Video Signal Processor (VSPD), and Display Unit (DU).

It has DPI/DSI interfaces and supports a maximum resolution of 1080p
along with 2 RPFs to support the blending of two picture layers and
raster operations (ROPs).

The DU module is connected to VSPD. Add RZ/G2L DU support for RZ/G2L
alike SoCs.

Signed-off-by: Biju Das 
---
Ref:
 
https://lore.kernel.org/linux-renesas-soc/os0pr01mb5922717e4ccfe07f3c25fbc986...@os0pr01mb5922.jpnprd01.prod.outlook.com/#t
v11->v12:
* Replaced rzg2l_du_write() with writel().
v10->v11:
* Replaced CONFIG_DRM_RCAR_VSP->CONFIG_VIDEO_RENESAS_VSP1 for building
  rzg2l_du_vsp driver.
* Dropped "rzg2l_du_regs.h" instead the relevant definitions defined in
  .c file.
* Dropped setting ditr5 based on latest HW manual 1.3.0/1.4.0
* Updated the comment for auto clear.
* Replaced writel()->rzg2l_du_write() in rzg2l_du_start_stop().
* Dropped CRC related functions as it does not have DISCOM.
* Replaced the variable possible_crtcs->possible_outputs in
  struct rzg2l_du_output_routing.
* Updated DMA_BIT_MASK from 40->32.
* Dropped unneeded struct drm_bridge from rzg2l_du_drv.h.
* Dropped colour keying support as it doesn't have planes.
* Added only RGB formats in rzg2l_du_format_infos.
* Dropped chroma planes from rzg2l_du_fb_create().
* Updated the comment for max_pitch in rzg2l_du_fb_create().
* Dropped possible_crtcs check in rzg2l_du_encoders_init().
* Dropped additional empty line from struct rzg2l_du_device.
v9->v10:
 * Dropped ARM64 dependency from Kconfig.
 * Sorted the configs alphabetically in Kconfig.
 * Dropped DRM_RCAR_VSP config option and make DRM_RZG2L_DU depend on
   VIDEO_RENESAS_VSP1.
 * On rzg2l_du_crtc_set_display_timing() replaced the setting of parent
   clk rate with dclk rate.
 * Added rzg2l_du_write() wrapper function.
 * Updated the comment atomic_begin->atomic_flush.
 * Dropped .atomic_check and .atomic_begin callback
 * Renamed __rzg2l_du_crtc_plane_atomic_check->__rzg2l_du_vsp_plane_atomic
   _check and moved it to rzg2l_du_vsp.c
 * Added struct clk in rzg2l_du_crtc.h
 * Dropped the variables mmio_offset,index,vblank_lock,vblank_wait,
   vblank_count from struct rzg2l_du_crtc.
 * Replaced the macro to_rzg2l_crtc with static inline functions.
 * Dropped the unneeded header files clk.h, io.h, mm.h, pm.h, slab.h,
   wait.h and drm_managed.h from rzg2l_du_drv.c.
 * Replaced DRM_INFO->drm_info
 * Dropped the callbacks prime_handle_to_fd, prime_fd_to_handle and
   gem_prime_mmap.
 * Replaced the callback remove->remove_new.
 * Dropped header file wait.h and added forward declarations struct clk and
   rzg2l_du_device from rzg2l_du_drv.h.
 * Dropped the dsi and dpad0_source variables from struct rzg2l_du_device.
 * Replaced the macro to_rzg2l_encoder with static inline functions.
 * Dropped header files dma-buf.h and wait.h from rzg2l_du_kms.c.
 * Dropped struct sg_table and added the scatterlist.h header file in
   rzg2l_du_vsp.h
 * Added container_of.h header file, forward declarations struct device and
   struct rzg2l_du_device in rzg2l_du_vsp.h.
v8->v9:
 * Dropped reset_control_assert() from error patch for rzg2l_du_crtc_get() as
   suggested by Philipp Zabel.
v7->v8:
 * Dropped RCar du lib and created RZ/G2L DU DRM driver by creating rz_du 
folder.
 * Updated KConfig and Makefile.
v6->v7:
 * Split DU lib and  RZ/G2L du driver as separate patch series as
   DU support added to more platforms based on RZ/G2L alike SoCs.
 * Rebased to latest drm-tip.
 * Added patch #2 for binding support for RZ/V2L DU
 * Added patch #4 for driver support for RZ/V2L DU
 * Added patch #5 for SoC DTSI support for RZ/G2L DU
 * Added patch #6 for SoC DTSI support for RZ/V2L DU
 * Added patch #7 for Enabling DU on SMARC EVK based on RZ/{G2L,V2L} SoCs.
 * Added patch #8 for Enabling DU on SMARC EVK based on RZ/G2LC SoC.
---
 drivers/gpu/drm/renesas/Kconfig   |   1 +
 drivers/gpu/drm/renesas/Makefile  |   1 +
 drivers/gpu/drm/renesas/rz-du/Kconfig |  12 +
 drivers/gpu/drm/renesas/rz-du/Makefile|   8 +
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c | 435 
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h |  89 
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c  | 176 +++
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h  |  78 +++
 .../gpu/drm/renesas/rz-du/rzg2l_du_encoder.c  |  72 +++
 .../gpu/drm/renesas/rz-du/rzg2l_du_encoder.h  |  32 ++
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c  | 441 
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.h  |  43 ++
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c  | 469 ++
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.h  |  97 
 14 files changed, 1954 insertions(+)
 create mode 100644 drivers/gpu/drm/renesas/rz-du/Kconfig
 create mode 100644 drivers/gpu/drm/renesas/rz-du/Makefile
 create mode 100644 drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
 create mode 100644 drivers/gpu/drm/renesas/rz-du/rzg2l_du_

[PATCH v3 11/15] drm/i915/dsi: Extract common soc_gpio_set_value() helper

2023-11-02 Thread Andy Shevchenko
Extract a common soc_gpio_set_value() helper that may be used by a few SoCs.

Signed-off-by: Andy Shevchenko 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 46 +++-
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index 0f9da0168a7b..9847a92fdfc3 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -243,6 +243,31 @@ static const u8 *mipi_exec_delay(struct intel_dsi 
*intel_dsi, const u8 *data)
return data;
 }
 
+static void soc_gpio_set_value(struct intel_connector *connector, const char 
*con_id,
+  u8 gpio_index, bool value)
+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   /* XXX: this table is a quick ugly hack. */
+   static struct gpio_desc *soc_gpio_table[U8_MAX + 1];
+   struct gpio_desc *gpio_desc = soc_gpio_table[gpio_index];
+
+   if (gpio_desc) {
+   gpiod_set_value(gpio_desc, value);
+   } else {
+   gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev,
+con_id, gpio_index,
+value ? GPIOD_OUT_HIGH : 
GPIOD_OUT_LOW);
+   if (IS_ERR(gpio_desc)) {
+   drm_err(&dev_priv->drm,
+   "GPIO index %u request failed (%pe)\n",
+   gpio_index, gpio_desc);
+   return;
+   }
+
+   soc_gpio_table[gpio_index] = gpio_desc;
+   }
+}
+
 static void vlv_gpio_set_value(struct intel_connector *connector,
   u8 gpio_source, u8 gpio_index, bool value)
 {
@@ -348,26 +373,7 @@ static void chv_gpio_set_value(struct intel_connector 
*connector,
 static void bxt_gpio_set_value(struct intel_connector *connector,
   u8 gpio_index, bool value)
 {
-   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-   /* XXX: this table is a quick ugly hack. */
-   static struct gpio_desc *bxt_gpio_table[U8_MAX + 1];
-   struct gpio_desc *gpio_desc = bxt_gpio_table[gpio_index];
-
-   if (!gpio_desc) {
-   gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev,
-NULL, gpio_index,
-value ? GPIOD_OUT_HIGH : 
GPIOD_OUT_LOW);
-   if (IS_ERR_OR_NULL(gpio_desc)) {
-   drm_err(&dev_priv->drm,
-   "GPIO index %u request failed (%ld)\n",
-   gpio_index, PTR_ERR(gpio_desc));
-   return;
-   }
-
-   bxt_gpio_table[gpio_index] = gpio_desc;
-   }
-
-   gpiod_set_value(gpio_desc, value);
+   soc_gpio_set_value(connector, NULL, gpio_index, value);
 }
 
 enum {
-- 
2.40.0.1.gaa8946217a0b



[PATCH v3 13/15] drm/i915/dsi: Prepare soc_gpio_set_value() to distinguish GPIO communities

2023-11-02 Thread Andy Shevchenko
Currently soc_gpio_set_value() supports only a single indexing for GPIO pin.
For CHV case, for example, we will need to distinguish community based index
from the one that VBT is using. Introduce an additional parameter to
soc_gpio_set_value() and its callers.

Signed-off-by: Andy Shevchenko 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index 552bc6564d79..b1736c1301ea 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -206,8 +206,8 @@ static const u8 *mipi_exec_delay(struct intel_dsi 
*intel_dsi, const u8 *data)
return data;
 }
 
-static void soc_gpio_set_value(struct intel_connector *connector, const char 
*con_id,
-  u8 gpio_index, bool value)
+static void soc_gpio_set_value(struct intel_connector *connector, u8 
gpio_index,
+  const char *con_id, u8 idx, bool value)
 {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
/* XXX: this table is a quick ugly hack. */
@@ -217,8 +217,7 @@ static void soc_gpio_set_value(struct intel_connector 
*connector, const char *co
if (gpio_desc) {
gpiod_set_value(gpio_desc, value);
} else {
-   gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev,
-con_id, gpio_index,
+   gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev, con_id, idx,
 value ? GPIOD_OUT_HIGH : 
GPIOD_OUT_LOW);
if (IS_ERR(gpio_desc)) {
drm_err(&dev_priv->drm,
@@ -232,8 +231,8 @@ static void soc_gpio_set_value(struct intel_connector 
*connector, const char *co
 }
 
 static void soc_opaque_gpio_set_value(struct intel_connector *connector,
- const char *chip, const char *con_id,
- u8 gpio_index, bool value)
+ u8 gpio_index, const char *chip,
+ const char *con_id, u8 idx, bool value)
 {
struct gpiod_lookup_table *lookup;
 
@@ -243,11 +242,11 @@ static void soc_opaque_gpio_set_value(struct 
intel_connector *connector,
 
lookup->dev_id = ":00:02.0";
lookup->table[0] =
-   GPIO_LOOKUP_IDX(chip, gpio_index, con_id, gpio_index, 
GPIO_ACTIVE_HIGH);
+   GPIO_LOOKUP_IDX(chip, idx, con_id, idx, GPIO_ACTIVE_HIGH);
 
gpiod_add_lookup_table(lookup);
 
-   soc_gpio_set_value(connector, con_id, gpio_index, value);
+   soc_gpio_set_value(connector, gpio_index, con_id, idx, value);
 
gpiod_remove_lookup_table(lookup);
kfree(lookup);
@@ -271,7 +270,8 @@ static void vlv_gpio_set_value(struct intel_connector 
*connector,
}
}
 
-   soc_opaque_gpio_set_value(connector, "INT33FC:01", "Panel N", 
gpio_index, value);
+   soc_opaque_gpio_set_value(connector, gpio_index,
+ "INT33FC:01", "Panel N", gpio_index, value);
 }
 
 static void chv_gpio_set_value(struct intel_connector *connector,
@@ -331,7 +331,7 @@ static void chv_gpio_set_value(struct intel_connector 
*connector,
 static void bxt_gpio_set_value(struct intel_connector *connector,
   u8 gpio_index, bool value)
 {
-   soc_gpio_set_value(connector, NULL, gpio_index, value);
+   soc_gpio_set_value(connector, gpio_index, NULL, gpio_index, value);
 }
 
 enum {
-- 
2.40.0.1.gaa8946217a0b



[PATCH v3 14/15] drm/i915/dsi: Replace poking of CHV GPIOs behind the driver's back

2023-11-02 Thread Andy Shevchenko
It's a dirty hack in the driver that pokes GPIO registers behind
the driver's back. Moreoever it might be problematic as simultaneous
I/O may hang the system, see the commit 0bd50d719b00 ("pinctrl:
cherryview: prevent concurrent access to GPIO controllers") for
the details. Taking all this into consideration replace the hack
with proper GPIO APIs being used.

Signed-off-by: Andy Shevchenko 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 47 +---
 1 file changed, 10 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index b1736c1301ea..ffc65c943b11 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -66,19 +66,6 @@ struct i2c_adapter_lookup {
 #define CHV_GPIO_IDX_START_SW  100
 #define CHV_GPIO_IDX_START_SE  198
 
-#define CHV_VBT_MAX_PINS_PER_FMLY  15
-
-#define CHV_GPIO_PAD_CFG0(f, i)(0x4400 + (f) * 0x400 + (i) * 8)
-#define  CHV_GPIO_GPIOEN   (1 << 15)
-#define  CHV_GPIO_GPIOCFG_GPIO (0 << 8)
-#define  CHV_GPIO_GPIOCFG_GPO  (1 << 8)
-#define  CHV_GPIO_GPIOCFG_GPI  (2 << 8)
-#define  CHV_GPIO_GPIOCFG_HIZ  (3 << 8)
-#define  CHV_GPIO_GPIOTXSTATE(state)   ((!!(state)) << 1)
-
-#define CHV_GPIO_PAD_CFG1(f, i)(0x4400 + (f) * 0x400 + (i) * 8 
+ 4)
-#define  CHV_GPIO_CFGLOCK  (1 << 31)
-
 /* ICL DSI Display GPIO Pins */
 #define  ICL_GPIO_DDSP_HPD_A   0
 #define  ICL_GPIO_L_VDDEN_11
@@ -278,23 +265,21 @@ static void chv_gpio_set_value(struct intel_connector 
*connector,
   u8 gpio_source, u8 gpio_index, bool value)
 {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-   u16 cfg0, cfg1;
-   u16 family_num;
-   u8 port;
 
if (connector->panel.vbt.dsi.seq_version >= 3) {
if (gpio_index >= CHV_GPIO_IDX_START_SE) {
/* XXX: it's unclear whether 255->57 is part of SE. */
-   gpio_index -= CHV_GPIO_IDX_START_SE;
-   port = CHV_IOSF_PORT_GPIO_SE;
+   soc_exec_opaque_gpio(connector, gpio_index, 
"INT33FF:03", "Panel SE",
+gpio_index - 
CHV_GPIO_IDX_START_SW, value);
} else if (gpio_index >= CHV_GPIO_IDX_START_SW) {
-   gpio_index -= CHV_GPIO_IDX_START_SW;
-   port = CHV_IOSF_PORT_GPIO_SW;
+   soc_exec_opaque_gpio(connector, gpio_index, 
"INT33FF:00", "Panel SW",
+gpio_index - 
CHV_GPIO_IDX_START_SW, value);
} else if (gpio_index >= CHV_GPIO_IDX_START_E) {
-   gpio_index -= CHV_GPIO_IDX_START_E;
-   port = CHV_IOSF_PORT_GPIO_E;
+   soc_exec_opaque_gpio(connector, gpio_index, 
"INT33FF:02", "Panel E",
+gpio_index - CHV_GPIO_IDX_START_E, 
value);
} else {
-   port = CHV_IOSF_PORT_GPIO_N;
+   soc_exec_opaque_gpio(connector, gpio_index, 
"INT33FF:01", "Panel N",
+gpio_index - CHV_GPIO_IDX_START_N, 
value);
}
} else {
/* XXX: The spec is unclear about CHV GPIO on seq v2 */
@@ -311,21 +296,9 @@ static void chv_gpio_set_value(struct intel_connector 
*connector,
return;
}
 
-   port = CHV_IOSF_PORT_GPIO_N;
+   soc_exec_opaque_gpio(connector, gpio_index, "INT33FF:01", 
"Panel N",
+gpio_index - CHV_GPIO_IDX_START_N, value);
}
-
-   family_num = gpio_index / CHV_VBT_MAX_PINS_PER_FMLY;
-   gpio_index = gpio_index % CHV_VBT_MAX_PINS_PER_FMLY;
-
-   cfg0 = CHV_GPIO_PAD_CFG0(family_num, gpio_index);
-   cfg1 = CHV_GPIO_PAD_CFG1(family_num, gpio_index);
-
-   vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_GPIO));
-   vlv_iosf_sb_write(dev_priv, port, cfg1, 0);
-   vlv_iosf_sb_write(dev_priv, port, cfg0,
- CHV_GPIO_GPIOEN | CHV_GPIO_GPIOCFG_GPO |
- CHV_GPIO_GPIOTXSTATE(value));
-   vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
 }
 
 static void bxt_gpio_set_value(struct intel_connector *connector,
-- 
2.40.0.1.gaa8946217a0b



[rft, PATCH v3 00/15] drm/i915/dsi: 2nd attempt to get rid of IOSF GPIO

2023-11-02 Thread Andy Shevchenko
DSI code for VBT has a set of ugly GPIO hacks, one of which is direct
talking to GPIO IP behind the actual driver's back. A second attempt
to fix that is here.

If I understood correctly, my approach should work in the similar way as
the current IOSF GPIO.

Hans, I believe you have some devices that use this piece of code,
is it possible to give a test run on (one of) them?

In v3:
- incorporated series by Jani
- incorporated couple of precursor patches by Hans
- added Rb tag for used to be first three patches (Andi)
- rebased on top of the above changes
- fixed indexing for multi-community devices, such as Cherry View

In v2:
- added a few cleanup patches
- reworked to use dynamic GPIO lookup tables
- converted CHV as well

Andy Shevchenko (8):
  drm/i915/dsi: Replace while(1) with one with clear exit condition
  drm/i915/dsi: Get rid of redundant 'else'
  drm/i915/dsi: Replace check with a (missing) MIPI sequence name
  drm/i915/dsi: Extract common soc_gpio_set_value() helper
  drm/i915/dsi: Replace poking of VLV GPIOs behind the driver's back
  drm/i915/dsi: Prepare soc_gpio_set_value() to distinguish GPIO
communities
  drm/i915/dsi: Replace poking of CHV GPIOs behind the driver's back
  drm/i915/iosf: Drop unused APIs

Hans de Goede (2):
  drm/i915/dsi: Remove GPIO lookup table at the end of
intel_dsi_vbt_gpio_init()
  drm/i915/dsi: Fix wrong initial value for GPIOs in bxt_exec_gpio()

Jani Nikula (5):
  drm/i915/dsi: assume BXT gpio works for non-native GPIO
  drm/i915/dsi: switch mipi_exec_gpio() from dev_priv to i915
  drm/i915/dsi: clarify GPIO exec sequence
  drm/i915/dsi: rename platform specific *_exec_gpio() to
*_gpio_set_value()
  drm/i915/dsi: bxt/icl GPIO set value do not need gpio source

 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 355 +++
 drivers/gpu/drm/i915/vlv_sideband.c  |  17 -
 drivers/gpu/drm/i915/vlv_sideband.h  |   3 -
 3 files changed, 137 insertions(+), 238 deletions(-)

-- 
2.40.0.1.gaa8946217a0b



Re: [PATCH 10/10] drm/tidss: Fix atomic_flush check

2023-11-02 Thread Francesco Dolcini
On Wed, Nov 01, 2023 at 11:17:47AM +0200, Tomi Valkeinen wrote:
> tidss_crtc_atomic_flush() checks if the crtc is enabled, and if not,
> returns immediately as there's no reason to do any register changes.
> 
> However, the code checks for 'crtc->state->enable', which does not
> reflect the actual HW state. We should instead look at the
> 'crtc->state->active' flag.
> 
> This causes the tidss_crtc_atomic_flush() to proceed with the flush even
> if the active state is false, which then causes us to hit the
> WARN_ON(!crtc->state->event) check.
> 
> Fix this by checking the active flag, and while at it, fix the related
> debug print which had "active" and "needs modeset" wrong way.

Candidate for stable? Add a Fixes tag?

Francesco



[PATCH v3 02/15] drm/i915/dsi: switch mipi_exec_gpio() from dev_priv to i915

2023-11-02 Thread Andy Shevchenko
From: Jani Nikula 

Follow the contemporary conventions.

Cc: Andy Shevchenko 
Cc: Hans de Goede 
Signed-off-by: Jani Nikula 
Signed-off-by: Andy Shevchenko 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index b2c0cc11f8c1..8b962f2ac475 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -454,11 +454,11 @@ static void icl_native_gpio_set_value(struct 
drm_i915_private *dev_priv,
 static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
 {
struct drm_device *dev = intel_dsi->base.base.dev;
-   struct drm_i915_private *dev_priv = to_i915(dev);
+   struct drm_i915_private *i915 = to_i915(dev);
struct intel_connector *connector = intel_dsi->attached_connector;
u8 gpio_source, gpio_index = 0, gpio_number;
bool value;
-   bool native = DISPLAY_VER(dev_priv) >= 11;
+   bool native = DISPLAY_VER(i915) >= 11;
 
if (connector->panel.vbt.dsi.seq_version >= 3)
gpio_index = *data++;
@@ -477,16 +477,16 @@ static const u8 *mipi_exec_gpio(struct intel_dsi 
*intel_dsi, const u8 *data)
/* pull up/down */
value = *data++ & 1;
 
-   drm_dbg_kms(&dev_priv->drm, "GPIO index %u, number %u, source %u, 
native %s, set to %s\n",
+   drm_dbg_kms(&i915->drm, "GPIO index %u, number %u, source %u, native 
%s, set to %s\n",
gpio_index, gpio_number, gpio_source, str_yes_no(native), 
str_on_off(value));
 
if (native)
-   icl_native_gpio_set_value(dev_priv, gpio_number, value);
-   else if (DISPLAY_VER(dev_priv) >= 11)
+   icl_native_gpio_set_value(i915, gpio_number, value);
+   else if (DISPLAY_VER(i915) >= 11)
bxt_exec_gpio(connector, gpio_source, gpio_index, value);
-   else if (IS_VALLEYVIEW(dev_priv))
+   else if (IS_VALLEYVIEW(i915))
vlv_exec_gpio(connector, gpio_source, gpio_number, value);
-   else if (IS_CHERRYVIEW(dev_priv))
+   else if (IS_CHERRYVIEW(i915))
chv_exec_gpio(connector, gpio_source, gpio_number, value);
else
bxt_exec_gpio(connector, gpio_source, gpio_index, value);
-- 
2.40.0.1.gaa8946217a0b



[PATCH v12 1/4] dt-bindings: display: Document Renesas RZ/G2L DU bindings

2023-11-02 Thread Biju Das
The RZ/G2L LCD controller is composed of Frame Compression Processor
(FCPVD), Video Signal Processor (VSPD), and Display Unit (DU).

The DU module supports the following hardware features
− Display Parallel Interface (DPI) and MIPI LINK Video Interface
− Display timing master
− Generates video timings
− Selecting the polarity of output DCLK, HSYNC, VSYNC, and DE
− Supports Progressive
− Input data format (from VSPD): RGB888, RGB666
− Output data format: same as Input data format
− Supporting Full HD (1920 pixels x 1080 lines) for MIPI-DSI Output
− Supporting WXGA (1280 pixels x 800 lines) for Parallel Output

This patch documents the DU module found on RZ/G2L LCDC.

Signed-off-by: Biju Das 
Reviewed-by: Rob Herring 
Reviewed-by: Laurent Pinchart 
---
v11->v12:
 * Dropped quotes in ref handle for renesas,vsps property.
 * Retained tags as it is trivial change.
v10->v11:
 * No change
v9->v10:
 * Added Rb tag from Laurent
 * Updated the commit description.
 * Updated description of the port by dropping the text "specified in
   Documentation/devicetree/bindings/graph.txt."
 * Dropped empty endpoint from example.
v8->v9:
 * No change
v7->v8:
 * No change
v6->v7:
 * No change
v5->v6:
 * No change.
v4->v5:
 * Added Rb tag from Rob.
v3->v4:
 * Changed compatible name from renesas,du-r9a07g044->renesas,r9a07g044-du
 * started using same compatible for RZ/G2{L,LC}
v3: New patch
---
 .../bindings/display/renesas,rzg2l-du.yaml| 121 ++
 1 file changed, 121 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml

diff --git a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml 
b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
new file mode 100644
index ..c0ad194c538d
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
@@ -0,0 +1,121 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/renesas,rzg2l-du.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/G2L Display Unit (DU)
+
+maintainers:
+  - Biju Das 
+  - Laurent Pinchart 
+
+description: |
+  These DT bindings describe the Display Unit embedded in the Renesas RZ/G2L
+  and RZ/V2L SoCs.
+
+properties:
+  compatible:
+enum:
+  - renesas,r9a07g044-du # RZ/G2{L,LC}
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: Main clock
+  - description: Register access clock
+  - description: Video clock
+
+  clock-names:
+items:
+  - const: aclk
+  - const: pclk
+  - const: vclk
+
+  resets:
+maxItems: 1
+
+  power-domains:
+maxItems: 1
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+description: |
+  The connections to the DU output video ports are modeled using the OF
+  graph bindings. The number of ports and their assignment are
+  model-dependent. Each port shall have a single endpoint.
+
+patternProperties:
+  "^port@[0-1]$":
+$ref: /schemas/graph.yaml#/properties/port
+unevaluatedProperties: false
+
+required:
+  - port@0
+
+unevaluatedProperties: false
+
+  renesas,vsps:
+$ref: /schemas/types.yaml#/definitions/phandle-array
+items:
+  items:
+- description: phandle to VSP instance that serves the DU channel
+- description: Channel index identifying the LIF instance in that VSP
+description:
+  A list of phandle and channel index tuples to the VSPs that handle the
+  memory interfaces for the DU channels.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - power-domains
+  - ports
+  - renesas,vsps
+
+additionalProperties: false
+
+examples:
+  # RZ/G2L DU
+  - |
+#include 
+#include 
+
+display@1089 {
+compatible = "renesas,r9a07g044-du";
+reg = <0x1089 0x1>;
+interrupts = ;
+clocks = <&cpg CPG_MOD R9A07G044_LCDC_CLK_A>,
+ <&cpg CPG_MOD R9A07G044_LCDC_CLK_P>,
+ <&cpg CPG_MOD R9A07G044_LCDC_CLK_D>;
+clock-names = "aclk", "pclk", "vclk";
+resets = <&cpg R9A07G044_LCDC_RESET_N>;
+power-domains = <&cpg>;
+
+renesas,vsps = <&vspd0 0>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+endpoint {
+remote-endpoint = <&dsi0_in>;
+};
+};
+port@1 {
+reg = <1>;
+};
+};
+};
+
+...
-- 
2.25.1



[PATCH v3 05/15] drm/i915/dsi: bxt/icl GPIO set value do not need gpio source

2023-11-02 Thread Andy Shevchenko
From: Jani Nikula 

Drop the unused parameter.

Cc: Andy Shevchenko 
Cc: Hans de Goede 
Signed-off-by: Jani Nikula 
Signed-off-by: Andy Shevchenko 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index f977d63a0ad4..4af43cf3cee0 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -346,7 +346,7 @@ static void chv_gpio_set_value(struct intel_connector 
*connector,
 }
 
 static void bxt_gpio_set_value(struct intel_connector *connector,
-  u8 gpio_source, u8 gpio_index, bool value)
+  u8 gpio_index, bool value)
 {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
/* XXX: this table is a quick ugly hack. */
@@ -486,13 +486,13 @@ static const u8 *mipi_exec_gpio(struct intel_dsi 
*intel_dsi, const u8 *data)
if (native)
icl_native_gpio_set_value(i915, gpio_number, value);
else if (DISPLAY_VER(i915) >= 11)
-   bxt_gpio_set_value(connector, gpio_source, gpio_index, value);
+   bxt_gpio_set_value(connector, gpio_index, value);
else if (IS_VALLEYVIEW(i915))
vlv_gpio_set_value(connector, gpio_source, gpio_number, value);
else if (IS_CHERRYVIEW(i915))
chv_gpio_set_value(connector, gpio_source, gpio_number, value);
else
-   bxt_gpio_set_value(connector, gpio_source, gpio_index, value);
+   bxt_gpio_set_value(connector, gpio_index, value);
 
return data + size;
 }
-- 
2.40.0.1.gaa8946217a0b



[PATCH v3 03/15] drm/i915/dsi: clarify GPIO exec sequence

2023-11-02 Thread Andy Shevchenko
From: Jani Nikula 

With the various sequence versions and pointer increments interleaved,
it's a bit hard to decipher what's going on. Add separate paths for
different sequence versions.

Cc: Andy Shevchenko 
Cc: Hans de Goede 
Signed-off-by: Jani Nikula 
Signed-off-by: Andy Shevchenko 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 31 +++-
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index 8b962f2ac475..11073efe26c0 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -456,26 +456,29 @@ static const u8 *mipi_exec_gpio(struct intel_dsi 
*intel_dsi, const u8 *data)
struct drm_device *dev = intel_dsi->base.base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_connector *connector = intel_dsi->attached_connector;
-   u8 gpio_source, gpio_index = 0, gpio_number;
+   u8 gpio_source = 0, gpio_index = 0, gpio_number;
bool value;
+   int size;
bool native = DISPLAY_VER(i915) >= 11;
 
-   if (connector->panel.vbt.dsi.seq_version >= 3)
-   gpio_index = *data++;
+   if (connector->panel.vbt.dsi.seq_version >= 3) {
+   size = 3;
 
-   gpio_number = *data++;
+   gpio_index = data[0];
+   gpio_number = data[1];
+   value = data[2] & BIT(0);
 
-   /* gpio source in sequence v2 only */
-   if (connector->panel.vbt.dsi.seq_version == 2)
-   gpio_source = (*data >> 1) & 3;
-   else
-   gpio_source = 0;
+   if (connector->panel.vbt.dsi.seq_version >= 4 && data[2] & 
BIT(1))
+   native = false;
+   } else {
+   size = 2;
 
-   if (connector->panel.vbt.dsi.seq_version >= 4 && *data & BIT(1))
-   native = false;
+   gpio_number = data[0];
+   value = data[1] & BIT(0);
 
-   /* pull up/down */
-   value = *data++ & 1;
+   if (connector->panel.vbt.dsi.seq_version == 2)
+   gpio_source = (data[1] >> 1) & 3;
+   }
 
drm_dbg_kms(&i915->drm, "GPIO index %u, number %u, source %u, native 
%s, set to %s\n",
gpio_index, gpio_number, gpio_source, str_yes_no(native), 
str_on_off(value));
@@ -491,7 +494,7 @@ static const u8 *mipi_exec_gpio(struct intel_dsi 
*intel_dsi, const u8 *data)
else
bxt_exec_gpio(connector, gpio_source, gpio_index, value);
 
-   return data;
+   return data + size;
 }
 
 #ifdef CONFIG_ACPI
-- 
2.40.0.1.gaa8946217a0b



[PATCH v3 09/15] drm/i915/dsi: Remove GPIO lookup table at the end of intel_dsi_vbt_gpio_init()

2023-11-02 Thread Andy Shevchenko
From: Hans de Goede 

To properly deal with GPIOs used in MIPI panel sequences a temporary
GPIO lookup will be used. Since there can only be 1 GPIO lookup table
for the ":00:02.0" device this will not work if the GPIO lookup
table used by intel_dsi_vbt_gpio_init() is still registered.

After getting the "backlight" and "panel" GPIOs the lookup table
registered by intel_dsi_vbt_gpio_init() is no longer necessary,
remove it so that another temporary lookup-table for the ":00:02.0"
device can be added.

Signed-off-by: Hans de Goede 
Signed-off-by: Andy Shevchenko 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 25 +++-
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index d270437217b3..8e6beef90e5e 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -955,6 +955,7 @@ void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, 
bool panel_is_on)
struct intel_connector *connector = intel_dsi->attached_connector;
struct mipi_config *mipi_config = connector->panel.vbt.dsi.config;
enum gpiod_flags flags = panel_is_on ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
+   struct gpiod_lookup_table *gpiod_lookup_table = NULL;
bool want_backlight_gpio = false;
bool want_panel_gpio = false;
struct pinctrl *pinctrl;
@@ -962,12 +963,12 @@ void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, 
bool panel_is_on)
 
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
mipi_config->pwm_blc == PPS_BLC_PMIC) {
-   gpiod_add_lookup_table(&pmic_panel_gpio_table);
+   gpiod_lookup_table = &pmic_panel_gpio_table;
want_panel_gpio = true;
}
 
if (IS_VALLEYVIEW(dev_priv) && mipi_config->pwm_blc == PPS_BLC_SOC) {
-   gpiod_add_lookup_table(&soc_panel_gpio_table);
+   gpiod_lookup_table = &soc_panel_gpio_table;
want_panel_gpio = true;
want_backlight_gpio = true;
 
@@ -984,6 +985,9 @@ void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, 
bool panel_is_on)
"Failed to set pinmux to PWM\n");
}
 
+   if (gpiod_lookup_table)
+   gpiod_add_lookup_table(gpiod_lookup_table);
+
if (want_panel_gpio) {
intel_dsi->gpio_panel = gpiod_get(dev->dev, "panel", flags);
if (IS_ERR(intel_dsi->gpio_panel)) {
@@ -1002,15 +1006,13 @@ void intel_dsi_vbt_gpio_init(struct intel_dsi 
*intel_dsi, bool panel_is_on)
intel_dsi->gpio_backlight = NULL;
}
}
+
+   if (gpiod_lookup_table)
+   gpiod_remove_lookup_table(gpiod_lookup_table);
 }
 
 void intel_dsi_vbt_gpio_cleanup(struct intel_dsi *intel_dsi)
 {
-   struct drm_device *dev = intel_dsi->base.base.dev;
-   struct drm_i915_private *dev_priv = to_i915(dev);
-   struct intel_connector *connector = intel_dsi->attached_connector;
-   struct mipi_config *mipi_config = connector->panel.vbt.dsi.config;
-
if (intel_dsi->gpio_panel) {
gpiod_put(intel_dsi->gpio_panel);
intel_dsi->gpio_panel = NULL;
@@ -1020,13 +1022,4 @@ void intel_dsi_vbt_gpio_cleanup(struct intel_dsi 
*intel_dsi)
gpiod_put(intel_dsi->gpio_backlight);
intel_dsi->gpio_backlight = NULL;
}
-
-   if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
-   mipi_config->pwm_blc == PPS_BLC_PMIC)
-   gpiod_remove_lookup_table(&pmic_panel_gpio_table);
-
-   if (IS_VALLEYVIEW(dev_priv) && mipi_config->pwm_blc == PPS_BLC_SOC) {
-   pinctrl_unregister_mappings(soc_pwm_pinctrl_map);
-   gpiod_remove_lookup_table(&soc_panel_gpio_table);
-   }
 }
-- 
2.40.0.1.gaa8946217a0b



[PATCH v3 12/15] drm/i915/dsi: Replace poking of VLV GPIOs behind the driver's back

2023-11-02 Thread Andy Shevchenko
It's a dirty hack in the driver that pokes GPIO registers behind
the driver's back. Moreoever it might be problematic as simultaneous
I/O may hang the system, see the commit 40ecab551232 ("pinctrl:
baytrail: Really serialize all register accesses") for the details.
Taking all this into consideration replace the hack with proper
GPIO APIs being used.

Signed-off-by: Andy Shevchenko 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 98 ++--
 1 file changed, 28 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index 9847a92fdfc3..552bc6564d79 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -55,43 +55,6 @@
 #define MIPI_VIRTUAL_CHANNEL_SHIFT 1
 #define MIPI_PORT_SHIFT3
 
-/* base offsets for gpio pads */
-#define VLV_GPIO_NC_0_HV_DDI0_HPD  0x4130
-#define VLV_GPIO_NC_1_HV_DDI0_DDC_SDA  0x4120
-#define VLV_GPIO_NC_2_HV_DDI0_DDC_SCL  0x4110
-#define VLV_GPIO_NC_3_PANEL0_VDDEN 0x4140
-#define VLV_GPIO_NC_4_PANEL0_BKLTEN0x4150
-#define VLV_GPIO_NC_5_PANEL0_BKLTCTL   0x4160
-#define VLV_GPIO_NC_6_HV_DDI1_HPD  0x4180
-#define VLV_GPIO_NC_7_HV_DDI1_DDC_SDA  0x4190
-#define VLV_GPIO_NC_8_HV_DDI1_DDC_SCL  0x4170
-#define VLV_GPIO_NC_9_PANEL1_VDDEN 0x4100
-#define VLV_GPIO_NC_10_PANEL1_BKLTEN   0x40E0
-#define VLV_GPIO_NC_11_PANEL1_BKLTCTL  0x40F0
-
-#define VLV_GPIO_PCONF0(base_offset)   (base_offset)
-#define VLV_GPIO_PAD_VAL(base_offset)  ((base_offset) + 8)
-
-struct gpio_map {
-   u16 base_offset;
-   bool init;
-};
-
-static struct gpio_map vlv_gpio_table[] = {
-   { VLV_GPIO_NC_0_HV_DDI0_HPD },
-   { VLV_GPIO_NC_1_HV_DDI0_DDC_SDA },
-   { VLV_GPIO_NC_2_HV_DDI0_DDC_SCL },
-   { VLV_GPIO_NC_3_PANEL0_VDDEN },
-   { VLV_GPIO_NC_4_PANEL0_BKLTEN },
-   { VLV_GPIO_NC_5_PANEL0_BKLTCTL },
-   { VLV_GPIO_NC_6_HV_DDI1_HPD },
-   { VLV_GPIO_NC_7_HV_DDI1_DDC_SDA },
-   { VLV_GPIO_NC_8_HV_DDI1_DDC_SCL },
-   { VLV_GPIO_NC_9_PANEL1_VDDEN },
-   { VLV_GPIO_NC_10_PANEL1_BKLTEN },
-   { VLV_GPIO_NC_11_PANEL1_BKLTCTL },
-};
-
 struct i2c_adapter_lookup {
u16 slave_addr;
struct intel_dsi *intel_dsi;
@@ -268,52 +231,47 @@ static void soc_gpio_set_value(struct intel_connector 
*connector, const char *co
}
 }
 
+static void soc_opaque_gpio_set_value(struct intel_connector *connector,
+ const char *chip, const char *con_id,
+ u8 gpio_index, bool value)
+{
+   struct gpiod_lookup_table *lookup;
+
+   lookup = kzalloc(struct_size(lookup, table, 2), GFP_KERNEL);
+   if (!lookup)
+   return;
+
+   lookup->dev_id = ":00:02.0";
+   lookup->table[0] =
+   GPIO_LOOKUP_IDX(chip, gpio_index, con_id, gpio_index, 
GPIO_ACTIVE_HIGH);
+
+   gpiod_add_lookup_table(lookup);
+
+   soc_gpio_set_value(connector, con_id, gpio_index, value);
+
+   gpiod_remove_lookup_table(lookup);
+   kfree(lookup);
+}
+
 static void vlv_gpio_set_value(struct intel_connector *connector,
   u8 gpio_source, u8 gpio_index, bool value)
 {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-   struct gpio_map *map;
-   u16 pconf0, padval;
-   u32 tmp;
-   u8 port;
 
-   if (gpio_index >= ARRAY_SIZE(vlv_gpio_table)) {
-   drm_dbg_kms(&dev_priv->drm, "unknown gpio index %u\n",
-   gpio_index);
-   return;
-   }
-
-   map = &vlv_gpio_table[gpio_index];
-
-   if (connector->panel.vbt.dsi.seq_version >= 3) {
-   /* XXX: this assumes vlv_gpio_table only has NC GPIOs. */
-   port = IOSF_PORT_GPIO_NC;
-   } else {
-   if (gpio_source == 0) {
-   port = IOSF_PORT_GPIO_NC;
-   } else if (gpio_source == 1) {
+   /* XXX: this assumes vlv_gpio_table only has NC GPIOs. */
+   if (connector->panel.vbt.dsi.seq_version < 3) {
+   if (gpio_source == 1) {
drm_dbg_kms(&dev_priv->drm, "SC gpio not supported\n");
return;
-   } else {
+   }
+   if (gpio_source > 1) {
drm_dbg_kms(&dev_priv->drm,
"unknown gpio source %u\n", gpio_source);
return;
}
}
 
-   pconf0 = VLV_GPIO_PCONF0(map->base_offset);
-   padval = VLV_GPIO_PAD_VAL(map->base_offset);
-
-   vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_GPIO));
-   if (!map->init) {
-   /* FIXME: remove constant below */
-   vlv_iosf_sb_write(dev_priv, port, pconf0, 0x2000CC00);
-   map->init = true;
-   }
-
-   tmp = 0x4 | value;
-   vlv_iosf_sb_write(dev_priv, port

Re: [rft, PATCH v3 00/15] drm/i915/dsi: 2nd attempt to get rid of IOSF GPIO

2023-11-02 Thread Andy Shevchenko
On Thu, Nov 02, 2023 at 05:12:13PM +0200, Andy Shevchenko wrote:
> DSI code for VBT has a set of ugly GPIO hacks, one of which is direct
> talking to GPIO IP behind the actual driver's back. A second attempt
> to fix that is here.
> 
> If I understood correctly, my approach should work in the similar way as
> the current IOSF GPIO.
> 
> Hans, I believe you have some devices that use this piece of code,
> is it possible to give a test run on (one of) them?

Subject should be "3rd attempt ..." :-)

> In v3:
> - incorporated series by Jani
> - incorporated couple of precursor patches by Hans
> - added Rb tag for used to be first three patches (Andi)
> - rebased on top of the above changes
> - fixed indexing for multi-community devices, such as Cherry View
> 
> In v2:
> - added a few cleanup patches
> - reworked to use dynamic GPIO lookup tables
> - converted CHV as well


-- 
With Best Regards,
Andy Shevchenko




[PATCH v3 07/15] drm/i915/dsi: Get rid of redundant 'else'

2023-11-02 Thread Andy Shevchenko
In the snippets like the following

if (...)
return / goto / break / continue ...;
else
...

the 'else' is redundant. Get rid of it.

Reviewed-by: Andi Shyti 
Signed-off-by: Andy Shevchenko 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 58 ++--
 1 file changed, 28 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index 290a112f1b63..4ed5ede9ec5b 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -142,7 +142,7 @@ static enum port intel_dsi_seq_port_to_port(struct 
intel_dsi *intel_dsi,
if (seq_port) {
if (intel_dsi->ports & BIT(PORT_B))
return PORT_B;
-   else if (intel_dsi->ports & BIT(PORT_C))
+   if (intel_dsi->ports & BIT(PORT_C))
return PORT_C;
}
 
@@ -670,8 +670,8 @@ static const char *sequence_name(enum mipi_seq seq_id)
 {
if (seq_id < ARRAY_SIZE(seq_name) && seq_name[seq_id])
return seq_name[seq_id];
-   else
-   return "(unknown)";
+
+   return "(unknown)";
 }
 
 static void intel_dsi_vbt_exec(struct intel_dsi *intel_dsi,
@@ -865,36 +865,34 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 
panel_id)
 * multiply by 100 to preserve remainder
 */
if (intel_dsi->video_mode == BURST_MODE) {
-   if (mipi_config->target_burst_mode_freq) {
-   u32 bitrate = intel_dsi_bitrate(intel_dsi);
+   u32 bitrate;
 
-   /*
-* Sometimes the VBT contains a slightly lower clock,
-* then the bitrate we have calculated, in this case
-* just replace it with the calculated bitrate.
-*/
-   if (mipi_config->target_burst_mode_freq < bitrate &&
-   intel_fuzzy_clock_check(
-   mipi_config->target_burst_mode_freq,
-   bitrate))
-   mipi_config->target_burst_mode_freq = bitrate;
-
-   if (mipi_config->target_burst_mode_freq < bitrate) {
-   drm_err(&dev_priv->drm,
-   "Burst mode freq is less than 
computed\n");
-   return false;
-   }
-
-   burst_mode_ratio = DIV_ROUND_UP(
-   mipi_config->target_burst_mode_freq * 100,
-   bitrate);
-
-   intel_dsi->pclk = DIV_ROUND_UP(intel_dsi->pclk * 
burst_mode_ratio, 100);
-   } else {
-   drm_err(&dev_priv->drm,
-   "Burst mode target is not set\n");
+   if (mipi_config->target_burst_mode_freq == 0) {
+   drm_err(&dev_priv->drm, "Burst mode target is not 
set\n");
return false;
}
+
+   bitrate = intel_dsi_bitrate(intel_dsi);
+
+   /*
+* Sometimes the VBT contains a slightly lower clock, then
+* the bitrate we have calculated, in this case just replace it
+* with the calculated bitrate.
+*/
+   if (mipi_config->target_burst_mode_freq < bitrate &&
+   intel_fuzzy_clock_check(mipi_config->target_burst_mode_freq,
+   bitrate))
+   mipi_config->target_burst_mode_freq = bitrate;
+
+   if (mipi_config->target_burst_mode_freq < bitrate) {
+   drm_err(&dev_priv->drm, "Burst mode freq is less than 
computed\n");
+   return false;
+   }
+
+   burst_mode_ratio =
+   DIV_ROUND_UP(mipi_config->target_burst_mode_freq * 100, 
bitrate);
+
+   intel_dsi->pclk = DIV_ROUND_UP(intel_dsi->pclk * 
burst_mode_ratio, 100);
} else
burst_mode_ratio = 100;
 
-- 
2.40.0.1.gaa8946217a0b



[PATCH v3 04/15] drm/i915/dsi: rename platform specific *_exec_gpio() to *_gpio_set_value()

2023-11-02 Thread Andy Shevchenko
From: Jani Nikula 

The lowest level functions are about setting GPIO values, not about
executing any sequences anymore.

Cc: Andy Shevchenko 
Cc: Hans de Goede 
Signed-off-by: Jani Nikula 
Signed-off-by: Andy Shevchenko 
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index 11073efe26c0..f977d63a0ad4 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -243,8 +243,8 @@ static const u8 *mipi_exec_delay(struct intel_dsi 
*intel_dsi, const u8 *data)
return data;
 }
 
-static void vlv_exec_gpio(struct intel_connector *connector,
- u8 gpio_source, u8 gpio_index, bool value)
+static void vlv_gpio_set_value(struct intel_connector *connector,
+  u8 gpio_source, u8 gpio_index, bool value)
 {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct gpio_map *map;
@@ -291,8 +291,8 @@ static void vlv_exec_gpio(struct intel_connector *connector,
vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
 }
 
-static void chv_exec_gpio(struct intel_connector *connector,
- u8 gpio_source, u8 gpio_index, bool value)
+static void chv_gpio_set_value(struct intel_connector *connector,
+  u8 gpio_source, u8 gpio_index, bool value)
 {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
u16 cfg0, cfg1;
@@ -345,8 +345,8 @@ static void chv_exec_gpio(struct intel_connector *connector,
vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
 }
 
-static void bxt_exec_gpio(struct intel_connector *connector,
- u8 gpio_source, u8 gpio_index, bool value)
+static void bxt_gpio_set_value(struct intel_connector *connector,
+  u8 gpio_source, u8 gpio_index, bool value)
 {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
/* XXX: this table is a quick ugly hack. */
@@ -486,13 +486,13 @@ static const u8 *mipi_exec_gpio(struct intel_dsi 
*intel_dsi, const u8 *data)
if (native)
icl_native_gpio_set_value(i915, gpio_number, value);
else if (DISPLAY_VER(i915) >= 11)
-   bxt_exec_gpio(connector, gpio_source, gpio_index, value);
+   bxt_gpio_set_value(connector, gpio_source, gpio_index, value);
else if (IS_VALLEYVIEW(i915))
-   vlv_exec_gpio(connector, gpio_source, gpio_number, value);
+   vlv_gpio_set_value(connector, gpio_source, gpio_number, value);
else if (IS_CHERRYVIEW(i915))
-   chv_exec_gpio(connector, gpio_source, gpio_number, value);
+   chv_gpio_set_value(connector, gpio_source, gpio_number, value);
else
-   bxt_exec_gpio(connector, gpio_source, gpio_index, value);
+   bxt_gpio_set_value(connector, gpio_source, gpio_index, value);
 
return data + size;
 }
-- 
2.40.0.1.gaa8946217a0b



  1   2   >