[PATCH v4a 30/38] timers: dma-buf: Use timer_shutdown_sync() for on stack timers

2022-11-04 Thread Steven Rostedt
From: "Steven Rostedt (Google)" 

Before a timer is released, timer_shutdown_sync() must be called.

Link: https://lore.kernel.org/all/20221104054053.431922...@goodmis.org/

Cc: Sumit Semwal 
Cc: "Christian König" 
Cc: linux-me...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-...@lists.linaro.org
Signed-off-by: Steven Rostedt (Google) 
---
 drivers/dma-buf/st-dma-fence.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma-buf/st-dma-fence.c b/drivers/dma-buf/st-dma-fence.c
index fb6e0a6ae2c9..5d3e7b503501 100644
--- a/drivers/dma-buf/st-dma-fence.c
+++ b/drivers/dma-buf/st-dma-fence.c
@@ -412,7 +412,7 @@ static int test_wait_timeout(void *arg)
 
err = 0;
 err_free:
-   del_timer_sync(&wt.timer);
+   timer_shutdown_sync(&wt.timer);
destroy_timer_on_stack(&wt.timer);
dma_fence_signal(wt.f);
dma_fence_put(wt.f);
-- 
2.35.1


[PATCH v4a 31/38] timers: drm: Use timer_shutdown_sync() for on stack timers

2022-11-04 Thread Steven Rostedt
From: "Steven Rostedt (Google)" 

Before a timer is released, timer_shutdown_sync() must be called.

Link: https://lore.kernel.org/all/20221104054053.431922...@goodmis.org/

Cc: "Noralf Trønnes" 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: dri-devel@lists.freedesktop.org
Cc: intel-...@lists.freedesktop.org
Signed-off-by: Steven Rostedt (Google) 
---
 drivers/gpu/drm/gud/gud_pipe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index 7c6dc2bcd14a..08429bdd57cf 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -272,7 +272,7 @@ static int gud_usb_bulk(struct gud_device *gdrm, size_t len)
 
usb_sg_wait(&ctx.sgr);
 
-   if (!del_timer_sync(&ctx.timer))
+   if (!timer_shutdown_sync(&ctx.timer))
ret = -ETIMEDOUT;
else if (ctx.sgr.status < 0)
ret = ctx.sgr.status;
-- 
2.35.1


[PATCH v4a 00/38] timers: Use timer_shutdown*() before freeing timers

2022-11-04 Thread Steven Rostedt


Back in April, I posted an RFC patch set to help mitigate a common issue
where a timer gets armed just before it is freed, and when the timer
goes off, it crashes in the timer code without any evidence of who the
culprit was. I got side tracked and never finished up on that patch set.
Since this type of crash is still our #1 crash we are seeing in the field,
it has become a priority again to finish it.

The last version of that patch set is here:

  https://lore.kernel.org/all/20221104054053.431922...@goodmis.org/

I'm calling this version 4a as it only has obvious changes were the timer that
is being shutdown is in the same function where it will be freed or released,
as this series should be "safe" for adding. I'll be calling the other patches
4b for the next merge window.

Patch 1 fixes an issue with sunrpc/xprt where it incorrectly uses
del_singleshot_timer_sync() for something that is not a oneshot timer. As this
will be converted to shutdown, this needs to be fixed first.

Patches 2-4 changes existing timer_shutdown() functions used locally in ARM and
some drivers to better namespace names.

Patch 5 implements the new timer_shutdown() and timer_shutdown_sync() functions
that disable re-arming the timer after they are called.

Patches 6-28 change all the locations where there's a kfree(), kfree_rcu(),
kmem_cache_free() and one call_rcu() call where the RCU function frees the
timer (the workqueue patch) in the same function as the del_timer{,_sync}() is
called on that timer, and there's no extra exit path between the del_timer and
freeing of the timer.

Patches 29-32 add timer_shutdown*() on on-stack timers that are about to be
released at the end of the function.

Patches 33-37 add timer_shutdown*() on module timers in the module exit code.

Patch 38 simply converts an open coded "shutdown" code into timer_shutdown(),
as a way timer_shutdown() disables the timer is by setting that timer function
to NULL.

Linus, I sorted the patches this way to let you see which you would think is
safe to go into this -rc. I honestly believe that they are all safe, but that's
just my own opinion.

This series is here:

  git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
timers-start

Head SHA1: f58b516a65bac76f1bfa00126856d6c6c3d24a40


Steven Rostedt (Google) (38):
  SUNRPC/xprt: Use del_timer_sync() instead of del_singleshot_timer_sync()
  ARM: spear: Do not use timer namespace for timer_shutdown() function
  clocksource/drivers/arm_arch_timer: Do not use timer namespace for 
timer_shutdown() function
  clocksource/drivers/sp804: Do not use timer namespace for 
timer_shutdown() function
  timers: Add timer_shutdown_sync() and timer_shutdown() to be called 
before freeing timers
  timers: sh: Use timer_shutdown_sync() before freeing timer
  timers: block: Use timer_shutdown_sync() before freeing timer
  timers: ACPI: Use timer_shutdown_sync() before freeing timer
  timers: atm: Use timer_shutdown_sync() before freeing timer
  timers: Bluetooth: Use timer_shutdown_sync() before freeing timer
  timers: drm: Use timer_shutdown_sync() before freeing timer
  timers: HID: Use timer_shutdown_sync() before freeing timer
  timers: Input: Use timer_shutdown_sync() before freeing timer
  timers: mISDN: Use timer_shutdown_sync() before freeing timer
  timers: leds: Use timer_shutdown_sync() before freeing timer
  timers: media: Use timer_shutdown_sync() before freeing timer
  timers: net: Use timer_shutdown_sync() before freeing timer
  timers: usb: Use timer_shutdown_sync() before freeing timer
  timers: nfc: pn533: Use timer_shutdown_sync() before freeing timer
  timers: pcmcia: Use timer_shutdown_sync() before freeing timer
  timers: scsi: Use timer_shutdown_sync() and timer_shutdown() before 
freeing timer
  timers: tty: Use timer_shutdown_sync() before freeing timer
  timers: ext4: Use timer_shutdown_sync() before freeing timer
  timers: fs/nilfs2: Use timer_shutdown_sync() before freeing timer
  timers: ALSA: Use timer_shutdown_sync() before freeing timer
  timers: jbd2: Use timer_shutdown() before freeing timer
  timers: sched/psi: Use timer_shutdown_sync() before freeing timer
  timers: workqueue: Use timer_shutdown_sync() before freeing timer
  random: use timer_shutdown_sync() for on stack timers
  timers: dma-buf: Use timer_shutdown_sync() for on stack timers
  timers: drm: Use timer_shutdown_sync() for on stack timers
  timers: media: Use timer_shutdown_sync() for on stack timers
  timers: s390/cmm: Use timer_shutdown_sync() before a module is released
  timers: atm: Use timer_shutdown_sync() before a module is released
  timers: hangcheck: Use timer_shutdown_sync() before a module is released
  timers: ipmi: Use timer_shutdown_sync() before a module is released
  timers: Input: Use timer_shutdown_sync() before a module is released
  timers: PM: 

[PATCH v4a 11/38] timers: drm: Use timer_shutdown_sync() before freeing timer

2022-11-04 Thread Steven Rostedt
From: "Steven Rostedt (Google)" 

Before a timer is freed, timer_shutdown_sync() must be called.

Link: https://lore.kernel.org/all/20221104054053.431922...@goodmis.org/

Cc: "Noralf Trønnes" 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: dri-devel@lists.freedesktop.org
Cc: intel-...@lists.freedesktop.org
Signed-off-by: Steven Rostedt (Google) 
---
 drivers/gpu/drm/i915/i915_sw_fence.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c 
b/drivers/gpu/drm/i915/i915_sw_fence.c
index 6fc0d1b89690..bfaa9a67dc35 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -465,7 +465,7 @@ static void irq_i915_sw_fence_work(struct irq_work *wrk)
struct i915_sw_dma_fence_cb_timer *cb =
container_of(wrk, typeof(*cb), work);
 
-   del_timer_sync(&cb->timer);
+   timer_shutdown_sync(&cb->timer);
dma_fence_put(cb->dma);
 
kfree_rcu(cb, rcu);
-- 
2.35.1


Re: [PATCH v2 1/2] drm/i915/guc: Properly initialise kernel contexts

2022-11-04 Thread Lucas De Marchi

On Wed, Nov 02, 2022 at 12:21:08PM -0700, john.c.harri...@intel.com wrote:

From: John Harrison 

If a context has already been registered prior to first submission
then context init code was not being called. The noticeable effect of
that was the scheduling priority was left at zero (meaning super high
priority) instead of being set to normal. This would occur with
kernel contexts at start of day as they are manually pinned up front
rather than on first submission. So add a call to initialise those
when they are pinned.

Signed-off-by: John Harrison 



Reviewed-by: Lucas De Marchi 

Lucas De Marchi 


---
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 4ccb29f9ac55c..941613be3b9dd 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4111,6 +4111,9 @@ static inline void guc_kernel_context_pin(struct 
intel_guc *guc,
if (context_guc_id_invalid(ce))
pin_guc_id(guc, ce);

+   if (!test_bit(CONTEXT_GUC_INIT, &ce->flags))
+   guc_context_init(ce);
+
try_context_registration(ce, true);
}

--
2.37.3



Re: [Intel-gfx] [PATCH 1/2] drm/i915/gt: Add GT oriented dmesg output

2022-11-04 Thread Ceraolo Spurio, Daniele




On 11/4/2022 10:25 AM, john.c.harri...@intel.com wrote:

From: John Harrison 

When trying to analyse bug reports from CI, customers, etc. it can be
difficult to work out exactly what is happening on which GT in a
multi-GT system. So add GT oriented debug/error message wrappers. If
used instead of the drm_ equivalents, you get the same output but with
a GT# prefix on it.

Signed-off-by: John Harrison 


The only downside to this is that we'll print "GT0: " even on single-GT 
devices. We could introduce a gt->info.name and print that, so we could 
have it different per-platform, but IMO it's not worth the effort.


Reviewed-by: Daniele Ceraolo Spurio 

I think it might be worth getting an ack from one of the maintainers to 
make sure we're all aligned on transitioning to these new logging macro 
for gt code.


Daniele


---
  drivers/gpu/drm/i915/gt/intel_gt.h | 15 +++
  1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
b/drivers/gpu/drm/i915/gt/intel_gt.h
index e0365d5562484..1e016fb0117a4 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -13,6 +13,21 @@
  struct drm_i915_private;
  struct drm_printer;
  
+#define GT_ERR(_gt, _fmt, ...) \

+   drm_err(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__)
+
+#define GT_WARN(_gt, _fmt, ...) \
+   drm_warn(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, 
##__VA_ARGS__)
+
+#define GT_NOTICE(_gt, _fmt, ...) \
+   drm_notice(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, 
##__VA_ARGS__)
+
+#define GT_INFO(_gt, _fmt, ...) \
+   drm_info(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, 
##__VA_ARGS__)
+
+#define GT_DBG(_gt, _fmt, ...) \
+   drm_dbg(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__)
+
  #define GT_TRACE(gt, fmt, ...) do {   \
const struct intel_gt *gt__ __maybe_unused = (gt);  \
GEM_TRACE("%s " fmt, dev_name(gt__->i915->drm.dev), \




[PATCH 2/2] drm/display/dp_mst: Fix drm_dp_mst_add_affected_dsc_crtcs() return code

2022-11-04 Thread Lyude Paul
Looks like that we're accidentally dropping a pretty important return code
here. For some reason, we just return -EINVAL if we fail to get the MST
topology state. This is wrong: error codes are important and should never
be squashed without being handled, which here seems to have the potential
to cause a deadlock.

Signed-off-by: Lyude Paul 
Fixes: 8ec046716ca8 ("drm/dp_mst: Add helper to trigger modeset on affected DSC 
MST CRTCs")
Cc:  # v5.6+
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index ecd22c038c8c0..51a46689cda70 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -5186,7 +5186,7 @@ int drm_dp_mst_add_affected_dsc_crtcs(struct 
drm_atomic_state *state, struct drm
mst_state = drm_atomic_get_mst_topology_state(state, mgr);
 
if (IS_ERR(mst_state))
-   return -EINVAL;
+   return PTR_ERR(mst_state);
 
list_for_each_entry(pos, &mst_state->payloads, next) {
 
-- 
2.37.3



[PATCH 1/2] drm/amdgpu/mst: Stop ignoring error codes and deadlocking

2022-11-04 Thread Lyude Paul
It appears that amdgpu makes the mistake of completely ignoring the return
values from the DP MST helpers, and instead just returns a simple
true/false. In this case, it seems to have come back to bite us because as
a result of simply returning false from
compute_mst_dsc_configs_for_state(), amdgpu had no way of telling when a
deadlock happened from these helpers. This could definitely result in some
kernel splats.

Signed-off-by: Lyude Paul 
Fixes: 8c20a1ed9b4f ("drm/amd/display: MST DSC compute fair share")
Cc: Harry Wentland 
Cc:  # v5.6+
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  18 +--
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 107 ++
 .../display/amdgpu_dm/amdgpu_dm_mst_types.h   |  12 +-
 3 files changed, 73 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 0db2a88cd4d7b..6f76b2c84cdb5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6462,7 +6462,7 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct 
drm_atomic_state *state,
struct drm_connector_state *new_con_state;
struct amdgpu_dm_connector *aconnector;
struct dm_connector_state *dm_conn_state;
-   int i, j;
+   int i, j, ret;
int vcpi, pbn_div, pbn, slot_num = 0;
 
for_each_new_connector_in_state(state, connector, new_con_state, i) {
@@ -6509,8 +6509,11 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct 
drm_atomic_state *state,
dm_conn_state->pbn = pbn;
dm_conn_state->vcpi_slots = slot_num;
 
-   drm_dp_mst_atomic_enable_dsc(state, aconnector->port, 
dm_conn_state->pbn,
-false);
+   ret = drm_dp_mst_atomic_enable_dsc(state, 
aconnector->port,
+  dm_conn_state->pbn, 
false);
+   if (ret != 0)
+   return ret;
+
continue;
}
 
@@ -9523,10 +9526,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
if (dc_resource_is_dsc_encoding_supported(dc)) {
-   if (!pre_validate_dsc(state, &dm_state, vars)) {
-   ret = -EINVAL;
+   ret = pre_validate_dsc(state, &dm_state, vars);
+   if (ret != 0)
goto fail;
-   }
}
 #endif
 
@@ -9621,9 +9623,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
}
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-   if (!compute_mst_dsc_configs_for_state(state, 
dm_state->context, vars)) {
+   ret = compute_mst_dsc_configs_for_state(state, 
dm_state->context, vars);
+   if (ret) {
DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() 
failed\n");
-   ret = -EINVAL;
goto fail;
}
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 6ff96b4bdda5c..30bc2e5058b70 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -864,25 +864,25 @@ static bool try_disable_dsc(struct drm_atomic_state 
*state,
return true;
 }
 
-static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
-struct dc_state *dc_state,
-struct dc_link *dc_link,
-struct dsc_mst_fairness_vars *vars,
-struct drm_dp_mst_topology_mgr 
*mgr,
-int *link_vars_start_index)
+static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
+   struct dc_state *dc_state,
+   struct dc_link *dc_link,
+   struct dsc_mst_fairness_vars *vars,
+   struct drm_dp_mst_topology_mgr *mgr,
+   int *link_vars_start_index)
 {
struct dc_stream_state *stream;
struct dsc_mst_fairness_params params[MAX_PIPES];
struct amdgpu_dm_connector *aconnector;
struct drm_dp_mst_topology_state *mst_state = 
drm_atomic_get_mst_topology_state(state, mgr);
int count = 0;
-   int i, k;
+   int i, k, ret;
bool debugfs_overwrite = false;
 
memset(params, 0, sizeof(params));
 
if (IS_ERR(mst_state))
-   return false;
+   return PTR_ERR(mst_state);
 
mst_state->pbn_div = 

Re: [RFC][PATCH v3 00/33] timers: Use timer_shutdown*() before freeing timers

2022-11-04 Thread Guenter Roeck
On Fri, Nov 04, 2022 at 01:40:53AM -0400, Steven Rostedt wrote:
> 
> Back in April, I posted an RFC patch set to help mitigate a common issue
> where a timer gets armed just before it is freed, and when the timer
> goes off, it crashes in the timer code without any evidence of who the
> culprit was. I got side tracked and never finished up on that patch set.
> Since this type of crash is still our #1 crash we are seeing in the field,
> it has become a priority again to finish it.
> 

After applying the patches attached below, everything compiles for me,
and there are no crashes. There are still various warnings, most in
networking. I know I need to apply some patch(es) to fix the networking
warnings, but I didn't entirely understand what exactly to apply, so
I didn't try.

Complete logs are at https://kerneltests.org/builders, on the bottom half
of the page (qemu tests, in the 'testing' column).

Guenter

---
Warnings:

ODEBUG: free active (active state 0) object type: timer_list hint: 
tcp_write_timer+0x0/0x1d0
from tcp_close -> __sk_destruct -> tcp_write_timer

ODEBUG: free active (active state 0) object type: timer_list hint: 
tcp_keepalive_timer+0x0/0x4c0
from tcp_close -> __sk_destruct -> tcp_keepalive_timer -> 
__del_timer_sync

ODEBUG: free active (active state 0) object type: timer_list hint: 
blk_rq_timed_out_timer+0x0/0x40
blk_free_queue_rcu -> blk_free_queue_rcu -> blk_rq_timed_out_timer

---
Changes applied on top of patch set to fix build errors:

diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c
index e979e2197f8e..5371c824786d 100644
--- a/arch/arm/mach-spear/time.c
+++ b/arch/arm/mach-spear/time.c
@@ -90,7 +90,7 @@ static void __init spear_clocksource_init(void)
200, 16, clocksource_mmio_readw_up);
 }
 
-static inline void timer_shutdown(struct clock_event_device *evt)
+static inline void spear_timer_shutdown(struct clock_event_device *evt)
 {
u16 val = readw(gpt_base + CR(CLKEVT));
 
@@ -101,7 +101,7 @@ static inline void timer_shutdown(struct clock_event_device 
*evt)
 
 static int spear_shutdown(struct clock_event_device *evt)
 {
-   timer_shutdown(evt);
+   spear_timer_shutdown(evt);
 
return 0;
 }
@@ -111,7 +111,7 @@ static int spear_set_oneshot(struct clock_event_device *evt)
u16 val;
 
/* stop the timer */
-   timer_shutdown(evt);
+   spear_timer_shutdown(evt);
 
val = readw(gpt_base + CR(CLKEVT));
val |= CTRL_ONE_SHOT;
@@ -126,7 +126,7 @@ static int spear_set_periodic(struct clock_event_device 
*evt)
u16 val;
 
/* stop the timer */
-   timer_shutdown(evt);
+   spear_timer_shutdown(evt);
 
period = clk_get_rate(gpt_clk) / HZ;
period >>= CTRL_PRESCALER16;
diff --git a/drivers/clocksource/arm_arch_timer.c 
b/drivers/clocksource/arm_arch_timer.c
index a7ff77550e17..9c3420a0d19d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -687,8 +687,8 @@ static irqreturn_t arch_timer_handler_virt_mem(int irq, 
void *dev_id)
return timer_handler(ARCH_TIMER_MEM_VIRT_ACCESS, evt);
 }
 
-static __always_inline int timer_shutdown(const int access,
- struct clock_event_device *clk)
+static __always_inline int arch_timer_shutdown(const int access,
+  struct clock_event_device *clk)
 {
unsigned long ctrl;
 
@@ -701,22 +701,22 @@ static __always_inline int timer_shutdown(const int 
access,
 
 static int arch_timer_shutdown_virt(struct clock_event_device *clk)
 {
-   return timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
+   return arch_timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
 }
 
 static int arch_timer_shutdown_phys(struct clock_event_device *clk)
 {
-   return timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
+   return arch_timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
 }
 
 static int arch_timer_shutdown_virt_mem(struct clock_event_device *clk)
 {
-   return timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
+   return arch_timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
 }
 
 static int arch_timer_shutdown_phys_mem(struct clock_event_device *clk)
 {
-   return timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
+   return arch_timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
 }
 
 static __always_inline void set_next_event(const int access, unsigned long evt,
diff --git a/drivers/clocksource/timer-sp804.c 
b/drivers/clocksource/timer-sp804.c
index e6a87f4af2b5..a3c38e1343f0 100644
--- a/drivers/clocksource/timer-sp804.c
+++ b/drivers/clocksource/timer-sp804.c
@@ -155,14 +155,14 @@ static irqreturn_t sp804_timer_interrupt(int irq, void 
*dev_id)
return IRQ_HANDLED;
 }
 
-static inline void timer_shutdown(struct clock_event_device *evt)
+static inline void sp804_timer_shutdown(struct clock_event_device *evt)
 {
writel(0, common_clkevt->ctrl);
 }
 
 static int sp

[PATCH v3] drm/nouveau: Add support to control backlight using bl_power for nva3.

2022-11-04 Thread Antonio Gomes
From: antoniospg 

Summary:

* Add support to turn on/off backlight when changing values in bl_power
  file. This is achieved by using function backlight_get_brightness()
  in nva3_set_intensity to get current brightness.

Test plan:

* Turn off:
echo 1 > /sys/class/backlight/nv_backlight/bl_power

* Turn on:
echo 0 > /sys/class/backlight/nv_backlight/bl_power

Signed-off-by: antoniospg 
---
 drivers/gpu/drm/nouveau/nouveau_backlight.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c 
b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index a2141d3d9b1d..5c82f5189b79 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -263,7 +263,11 @@ nva3_set_intensity(struct backlight_device *bd)
u32 div, val;
 
div = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
-   val = (bd->props.brightness * div) / 100;
+
+   val = backlight_get_brightness(bd);
+   if (val)
+   val = (val * div) / 100;
+
if (div) {
nvif_wr32(device, NV50_PDISP_SOR_PWM_CTL(or),
  val |
-- 
2.25.1



[PATCH v3] drm/nouveau: Add support to control backlight using bl_power for nva3.

2022-11-04 Thread Antonio Gomes
From: antoniospg 

Summary:

* Add support to turn on/off backlight when changing values in bl_power
  file. This is achieved by using function backlight_get_brightness()
  in nva3_set_intensity to get current brightness.

Test plan:

* Turn off:
echo 1 > /sys/class/backlight/nv_backlight/bl_power

* Turn on:
echo 0 > /sys/class/backlight/nv_backlight/bl_power

Signed-off-by: antoniospg 
---
 drivers/gpu/drm/nouveau/nouveau_backlight.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c 
b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index a2141d3d9b1d..5c82f5189b79 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -263,7 +263,11 @@ nva3_set_intensity(struct backlight_device *bd)
u32 div, val;
 
div = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
-   val = (bd->props.brightness * div) / 100;
+
+   val = backlight_get_brightness(bd);
+   if (val)
+   val = (val * div) / 100;
+
if (div) {
nvif_wr32(device, NV50_PDISP_SOR_PWM_CTL(or),
  val |
-- 
2.25.1



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

2022-11-04 Thread pr-tracker-bot
The pull request you sent on Fri, 4 Nov 2022 13:21:02 +1000:

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

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

Thank you!

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


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

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

New stuff for 6.2.

The following changes since commit 9abf2313adc1ca1b6180c508c25f22f9395cc780:

  Linux 6.1-rc1 (2022-10-16 15:36:24 -0700)

are available in the Git repository at:

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

for you to fetch changes up to fcf00f8d29f2fc6bf00531a1447be28b99073cc3:

  drm/amdkfd: Remove skiping userptr buffer mapping when mmu notifier marks it 
as invalid (2022-11-04 16:05:54 -0400)


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

amdgpu:
- Add TMZ support for GC 11.0.1
- More IP version check conversions
- Mode2 reset fixes for sienna cichlid
- SMU 13.x fixes
- RAS enablement on MP 13.x
- Replace kmap with kmap_local_page()
- Misc Clang warning fixes
- SR-IOV fixes for GC 11.x
- PCI AER fix
- DCN 3.2.x commit sequence rework
- SDMA 4.x doorbell fix
- Expose additional new GC 11.x firmware versions
- Misc code cleanups
- S0i3 fixes
- More DC FPU cleanup
- Add more DC kerneldoc
- Misc spelling and grammer fixes
- DCN 3.1.x fixes
- Plane modifier fix
- MCA RAS enablement
- Secure display locking fix
- RAS TA rework
- RAS EEPROM fixes
- Fail suspend if eviction fails
- Drop AMD specific DSC workarounds in favor of drm EDID quirks
- SR-IOV suspend/resume fixes
- Enable DCN support for ARM
- Enable secure display on DCN 2.1

amdkfd:
- Cache size fixes for GC 10.3.x
- kfd_dev struct cleanup
- GC11.x CWSR trap handler fix
- Userptr fixes
- Warning fixes

radeon:
- Replace kmap with kmap_local_page()

UAPI:
- Expose additional new GC 11.x firmware versions via the existing INFO query

drm:
- Add some new EDID DSC quirks


Alan Liu (3):
  drm/amd/display: Implement secure display on DCN21
  drm/amd/display: Drop struct crc_region and reuse struct rect
  drm/amdgpu: Move the mutex_lock to protect the return status of 
securedisplay command buffer

Alex Deucher (6):
  drm/amdgpu: convert vega20_ih.c to IP version checks
  drm/amdgpu: convert amdgpu_amdkfd_gpuvm.c to IP version checks
  drm/amdgpu: fix sdma doorbell init ordering on APUs
  drm/amdgpu/gfx9: set gfx.funcs in early init
  drm/amdgpu/gfx10: set gfx.funcs in early init
  drm/amdgpu/gfx11: set gfx.funcs in early init

Alvin Lee (4):
  drm/amd/display: Don't return false if no stream
  drm/amd/display: Remove optimization for VRR updates
  drm/amd/display: Enable timing sync on DCN32
  drm/amd/display: Don't enable ODM + MPO

Anthony Koo (2):
  drm/amd/display: Document part of the DMUB cmd
  drm/amd/display: [FW Promotion] Release 0.0.141.0

Ao Zhong (3):
  drm/amd/display: move remaining FPU code to dml folder
  drm/amd/display: move remaining FPU code to dml folder
  drm/amd/display: add DCN support for ARM64

Aric Cyr (4):
  drm/amd/display: 3.2.208
  drm/amd/display: Fix SDR visual confirm
  drm/amd/display: 3.2.209
  drm/amd/display: 3.2.210

Arunpravin Paneer Selvam (1):
  drm/amdgpu: Fix for BO move issue

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

Bhawanpreet Lakha (1):
  drm/amd/display: Fix HDCP 1.X 1A-04 failing

Candice Li (5):
  drm/amdgpu: Optimize RAS TA initialization and TA unload funcs
  drm/amdgpu: Optimize TA load/unload/invoke debugfs interfaces
  drm/amdgpu: Update ras eeprom support for smu v13_0_0 and v13_0_10
  drm/amdgpu: Add EEPROM I2C address support for ip discovery
  drm/amdgpu: Enable GFX RAS feature for gfx v11_0_3

Charlene Liu (2):
  drm/amd/display: Update DML formula
  drm/amd/display: Fix null pointer issues found in emulation

Chengming Gui (1):
  drm/amdgpu: fix pstate setting issue

Danijel Slivka (1):
  drm/amdgpu: set vm_update_mode=0 as default for Sienna Cichlid in SRIOV 
case

David Francis (1):
  drm/amd: Add IMU fw version to fw version queries

Deming Wang (1):
  drm/amdkfd: use vma_lookup() instead of find_vma()

Dillon Varone (4):
  drm/amd/display: Update latencies on DCN321
  drm/amd/display: Set memclk levels to be at least 1 for dcn32
  drm/amd/display: Reinit DPG when exiting dynamic ODM
  drm/amd/display: Check validation passed after applying pipe split changes

Dmytro Laktyushkin (1):
  drm/amd/display: correctly populate dcn315 clock table

Eric Bernstein (1):
  drm/amd/display: Include virtual signal to set k1 and k2 values

Evan Quan (3):
  drm/amd/pm: fulfill SMU13.0.0 cstate control interface
  drm/amd/pm: fulfill SMU13.0.7 cstate control interface
  drm/amd/pm: disable cstate feature for gpu reset scenario

Fabio M. De Francesco (2):
  drm/radeon: Replace kmap() with kmap_local_page()
  drm/amd/amdgpu: Replace kmap() with kmap_local_page()

Fangzhi Zuo (3):
  drm/amd/display: Add UHBR135 and UHBR20 into debugfs
  drm/amd/display: Ignore Cable ID Featur

Re: [PATCH] drm/panfrost: Update io-pgtable API

2022-11-04 Thread Dmitry Osipenko
On 11/4/22 23:37, Robin Murphy wrote:
> On 2022-11-04 20:11, Dmitry Osipenko wrote:
>> On 8/23/22 01:01, Robin Murphy wrote:
>>> Convert to io-pgtable's bulk {map,unmap}_pages() APIs, to help the old
>>> single-page interfaces eventually go away. Unmapping heap BOs still
>>> wants to be done a page at a time, but everything else can get the full
>>> benefit of the more efficient interface.
>>>
>>> Signed-off-by: Robin Murphy 
>>> ---
>>>   drivers/gpu/drm/panfrost/panfrost_mmu.c | 40 +++--
>>>   1 file changed, 25 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c
>>> b/drivers/gpu/drm/panfrost/panfrost_mmu.c
>>> index b285a8001b1d..e246d914e7f6 100644
>>> --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
>>> +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
>>> @@ -248,11 +248,15 @@ void panfrost_mmu_reset(struct panfrost_device
>>> *pfdev)
>>>   mmu_write(pfdev, MMU_INT_MASK, ~0);
>>>   }
>>>   -static size_t get_pgsize(u64 addr, size_t size)
>>> +static size_t get_pgsize(u64 addr, size_t size, size_t *count)
>>>   {
>>> -    if (addr & (SZ_2M - 1) || size < SZ_2M)
>>> -    return SZ_4K;
>>> +    size_t blk_offset = -addr % SZ_2M;
>>>   +    if (blk_offset || size < SZ_2M) {
>>> +    *count = min_not_zero(blk_offset, size) / SZ_4K;
>>> +    return SZ_4K;
>>> +    }
>>> +    *count = size / SZ_2M;
>>>   return SZ_2M;
>>>   }
>>>   @@ -287,12 +291,16 @@ static int mmu_map_sg(struct panfrost_device
>>> *pfdev, struct panfrost_mmu *mmu,
>>>   dev_dbg(pfdev->dev, "map: as=%d, iova=%llx, paddr=%lx,
>>> len=%zx", mmu->as, iova, paddr, len);
>>>     while (len) {
>>> -    size_t pgsize = get_pgsize(iova | paddr, len);
>>> +    size_t pgcount, mapped = 0;
>>> +    size_t pgsize = get_pgsize(iova | paddr, len, &pgcount);
>>>   -    ops->map(ops, iova, paddr, pgsize, prot, GFP_KERNEL);
>>> -    iova += pgsize;
>>> -    paddr += pgsize;
>>> -    len -= pgsize;
>>> +    ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot,
>>> +   GFP_KERNEL, &mapped);
>>> +    /* Don't get stuck if things have gone wrong */
>>> +    mapped = max(mapped, pgsize);
>>> +    iova += mapped;
>>> +    paddr += mapped;
>>> +    len -= mapped;
>>>   }
>>>   }
>>>   @@ -344,15 +352,17 @@ void panfrost_mmu_unmap(struct
>>> panfrost_gem_mapping *mapping)
>>>   mapping->mmu->as, iova, len);
>>>     while (unmapped_len < len) {
>>> -    size_t unmapped_page;
>>> -    size_t pgsize = get_pgsize(iova, len - unmapped_len);
>>> +    size_t unmapped_page, pgcount;
>>> +    size_t pgsize = get_pgsize(iova, len - unmapped_len, &pgcount);
>>>   -    if (ops->iova_to_phys(ops, iova)) {
>>> -    unmapped_page = ops->unmap(ops, iova, pgsize, NULL);
>>> -    WARN_ON(unmapped_page != pgsize);
>>> +    if (bo->is_heap)
>>> +    pgcount = 1;
>>> +    if (!bo->is_heap || ops->iova_to_phys(ops, iova)) {
>>> +    unmapped_page = ops->unmap_pages(ops, iova, pgsize,
>>> pgcount, NULL);
>>> +    WARN_ON(unmapped_page != pgsize * pgcount);
>>
>> This patch causes this WARN_ON to trigger. It doesn't happen all the
>> time, I see that the whole unmapped area is mapped. Initially, I thought
>> that this happens because it tries to unmap a partially mapped range,
>> but I checked that ops->iova_to_phys() returns address for all 4k chunks.
>>
>> For example the pgsize * pgcount = 0x800, while returned
>> unmapped_page = 0x600.
>>
>> I don't see this problem with this patch reverted. This is using today's
>> linux-next. Any ideas?
> 
> What's the base IOVA in such a case? I'm wondering if the truncated size
> lines up to any interesting boundary. Presumably you're not seeing any
> additional warnings from io-pgtable itself?

No warnings from io-pgtable. It succeeds for 0x3200 and fails for
0x3a00 using same size 0x800. It actually fails only for the
0x3a00 as far as I see from my logs. Perhaps it indeed has to do
something with the boundary.

-- 
Best regards,
Dmitry



Re: [RFC][PATCH v3 00/33] timers: Use timer_shutdown*() before freeing timers

2022-11-04 Thread Guenter Roeck
On Fri, Nov 04, 2022 at 04:38:34PM -0400, Steven Rostedt wrote:
> On Fri, 4 Nov 2022 15:42:09 -0400
> Steven Rostedt  wrote:
> 
[ ... ]
> 
> > drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
> > drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
> > drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
> > drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown = 
> > ast2600_timer_shutdown;
> > drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown = 
> > fttmr010_timer_shutdown;
> > drivers/clocksource/timer-fttmr010.c:   fttmr010->clkevt.set_state_shutdown 
> > = fttmr010->timer_shutdown;
> > drivers/clocksource/timer-fttmr010.c:   fttmr010->clkevt.tick_resume = 
> > fttmr010->timer_shutdown;
> 
> I won't touch structure fields though.
> 

Agreed, same here.

Guenter


Re: [RFC][PATCH v3 00/33] timers: Use timer_shutdown*() before freeing timers

2022-11-04 Thread Guenter Roeck
On Fri, Nov 04, 2022 at 03:42:09PM -0400, Steven Rostedt wrote:
> On Fri, 4 Nov 2022 12:22:32 -0700
> Guenter Roeck  wrote:
> 
> > Unfortunately the renaming caused some symbol conflicts.
> > 
> > Global definition: timer_shutdown
> > 
> >   File Line
> > 0 time.c93 static inline void timer_shutdown(struct 
> > clock_event_device *evt)
> > 1 arm_arch_timer.c 690 static __always_inline int timer_shutdown(const int 
> > access,
> > 2 timer-fttmr010.c 105 int (*timer_shutdown)(struct clock_event_device 
> > *evt);
> > 3 timer-sp804.c158 static inline void timer_shutdown(struct 
> > clock_event_device *evt)
> > 4 timer.h  239 static inline int timer_shutdown(struct timer_list 
> > *timer)
> 
> $ git grep '\btimer_shutdown'
> arch/arm/mach-spear/time.c:static inline void timer_shutdown(struct 
> clock_event_device *evt)
> arch/arm/mach-spear/time.c: timer_shutdown(evt);
> arch/arm/mach-spear/time.c: timer_shutdown(evt);
> arch/arm/mach-spear/time.c: timer_shutdown(evt);
> drivers/clocksource/arm_arch_timer.c:static __always_inline int 
> timer_shutdown(const int access,
> drivers/clocksource/arm_arch_timer.c:   return 
> timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
> drivers/clocksource/arm_arch_timer.c:   return 
> timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
> drivers/clocksource/arm_arch_timer.c:   return 
> timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
> drivers/clocksource/arm_arch_timer.c:   return 
> timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
> drivers/clocksource/timer-fttmr010.c:   int (*timer_shutdown)(struct 
> clock_event_device *evt);
> drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
> drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
> drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
> drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown = 
> ast2600_timer_shutdown;
> drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown = 
> fttmr010_timer_shutdown;
> drivers/clocksource/timer-fttmr010.c:   fttmr010->clkevt.set_state_shutdown = 
> fttmr010->timer_shutdown;
> drivers/clocksource/timer-fttmr010.c:   fttmr010->clkevt.tick_resume = 
> fttmr010->timer_shutdown;
> drivers/clocksource/timer-sp804.c:static inline void timer_shutdown(struct 
> clock_event_device *evt)
> drivers/clocksource/timer-sp804.c:  timer_shutdown(evt);
> drivers/clocksource/timer-sp804.c:  timer_shutdown(evt);
> 
> Honestly, I think these need to be renamed, as "timer_shutdown()"
> should be specific to the timer code, and not individual timers.

Yes, that is what I did locally. I am repeating my test now with that
change made.

Guenter


Re: Coverity: kfd_parse_subtype_cache(): Memory - corruptions

2022-11-04 Thread Felix Kuehling

On 2022-11-04 15:41, coverity-bot wrote:

Hello!

This is an experimental semi-automated report about issues detected by
Coverity from a scan of next-20221104 as part of the linux-next scan project:
https://scan.coverity.com/projects/linux-next-weekly-scan

You're getting this email because you were associated with the identified
lines of code (noted below) that were touched by commits:

   Fri Dec 8 23:08:59 2017 -0500
 3a87177eb141 ("drm/amdkfd: Add topology support for dGPUs")

Coverity reported the following:

*** CID 1527133:  Memory - corruptions  (OVERRUN)
drivers/gpu/drm/amd/amdkfd/kfd_crat.c:1113 in kfd_parse_subtype_cache()
1107props->cache_size = cache->cache_size;
1108props->cacheline_size = cache->cache_line_size;
1109props->cachelines_per_tag = 
cache->lines_per_tag;
1110props->cache_assoc = cache->associativity;
props->cache_latency = cache->cache_latency;
1112
vvv CID 1527133:  Memory - corruptions  (OVERRUN)
vvv Overrunning array "cache->sibling_map" of 32 bytes by passing it to a function 
which accesses it at byte offset 63 using argument "64UL". [Note: The source code 
implementation of the function has been overridden by a builtin model.]
1113memcpy(props->sibling_map, cache->sibling_map,
1114sizeof(props->sibling_map));
1115
1116/* set the sibling_map_size as 32 for CRAT from 
ACPI */
1117props->sibling_map_size = CRAT_SIBLINGMAP_SIZE;
1118

If this is a false positive, please let us know so we can mark it as
such, or teach the Coverity rules to be smarter. If not, please make
sure fixes get into linux-next. :) For patches fixing this, please
include these lines (but double-check the "Fixes" first):

Reported-by: coverity-bot 
Addresses-Coverity-ID: 1527133 ("Memory - corruptions")
Fixes: 3a87177eb141 ("drm/amdkfd: Add topology support for dGPUs")

I'm not sure why this suddenly appeared after 5 years, but the read
over-run looks legit:



I think this was introduced by a more recent patch that was in fact 
meant to fix an array overrun on HW that is outgrowing the CRAT sibling 
map size:



commit 0938fbeb6f53fc44bc9b19784dee28496e68ba0c
Author: Ma Jun 
Date:   Wed Nov 2 15:53:26 2022 +0800

    drm/amdkfd: Fix the warning of array-index-out-of-bounds

    For some GPUs with more CUs, the original sibling_map[32]
    in struct crat_subtype_cache is not enough
    to save the cache information when create the VCRAT table,
    so skip filling the struct crat_subtype_cache info instead
    fill struct kfd_cache_properties directly to fix this problem.

    Signed-off-by: Ma Jun 
    Reviewed-by: Felix Kuehling 
    Signed-off-by: Alex Deucher 

I added Ma Jun to the email.

Regards,
  Felix




struct crat_subtype_cache {
 ...
 uint8_t sibling_map[CRAT_SIBLINGMAP_SIZE];

#define CRAT_SIBLINGMAP_SIZE32


struct kfd_cache_properties {
 ...
 uint8_t sibling_map[CACHE_SIBLINGMAP_SIZE];

#define CACHE_SIBLINGMAP_SIZE 64

Thanks for your attention!



Re: [RFC][PATCH v3 00/33] timers: Use timer_shutdown*() before freeing timers

2022-11-04 Thread Steven Rostedt
On Fri, 4 Nov 2022 15:42:09 -0400
Steven Rostedt  wrote:

> $ git grep '\btimer_shutdown'
> arch/arm/mach-spear/time.c:static inline void timer_shutdown(struct 
> clock_event_device *evt)
> arch/arm/mach-spear/time.c: timer_shutdown(evt);
> arch/arm/mach-spear/time.c: timer_shutdown(evt);
> arch/arm/mach-spear/time.c: timer_shutdown(evt);
> drivers/clocksource/arm_arch_timer.c:static __always_inline int 
> timer_shutdown(const int access,
> drivers/clocksource/arm_arch_timer.c:   return 
> timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
> drivers/clocksource/arm_arch_timer.c:   return 
> timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
> drivers/clocksource/arm_arch_timer.c:   return 
> timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
> drivers/clocksource/arm_arch_timer.c:   return 
> timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
> drivers/clocksource/timer-fttmr010.c:   int (*timer_shutdown)(struct 
> clock_event_device *evt);



> drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
> drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
> drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
> drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown = 
> ast2600_timer_shutdown;
> drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown = 
> fttmr010_timer_shutdown;
> drivers/clocksource/timer-fttmr010.c:   fttmr010->clkevt.set_state_shutdown = 
> fttmr010->timer_shutdown;
> drivers/clocksource/timer-fttmr010.c:   fttmr010->clkevt.tick_resume = 
> fttmr010->timer_shutdown;

I won't touch structure fields though.

-- Steve


> drivers/clocksource/timer-sp804.c:static inline void timer_shutdown(struct 
> clock_event_device *evt)
> drivers/clocksource/timer-sp804.c:  timer_shutdown(evt);
> drivers/clocksource/timer-sp804.c:  timer_shutdown(evt);


Re: [PATCH] drm/panfrost: Update io-pgtable API

2022-11-04 Thread Robin Murphy

On 2022-11-04 20:11, Dmitry Osipenko wrote:

On 8/23/22 01:01, Robin Murphy wrote:

Convert to io-pgtable's bulk {map,unmap}_pages() APIs, to help the old
single-page interfaces eventually go away. Unmapping heap BOs still
wants to be done a page at a time, but everything else can get the full
benefit of the more efficient interface.

Signed-off-by: Robin Murphy 
---
  drivers/gpu/drm/panfrost/panfrost_mmu.c | 40 +++--
  1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index b285a8001b1d..e246d914e7f6 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -248,11 +248,15 @@ void panfrost_mmu_reset(struct panfrost_device *pfdev)
mmu_write(pfdev, MMU_INT_MASK, ~0);
  }
  
-static size_t get_pgsize(u64 addr, size_t size)

+static size_t get_pgsize(u64 addr, size_t size, size_t *count)
  {
-   if (addr & (SZ_2M - 1) || size < SZ_2M)
-   return SZ_4K;
+   size_t blk_offset = -addr % SZ_2M;
  
+	if (blk_offset || size < SZ_2M) {

+   *count = min_not_zero(blk_offset, size) / SZ_4K;
+   return SZ_4K;
+   }
+   *count = size / SZ_2M;
return SZ_2M;
  }
  
@@ -287,12 +291,16 @@ static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu,

dev_dbg(pfdev->dev, "map: as=%d, iova=%llx, paddr=%lx, len=%zx", 
mmu->as, iova, paddr, len);
  
  		while (len) {

-   size_t pgsize = get_pgsize(iova | paddr, len);
+   size_t pgcount, mapped = 0;
+   size_t pgsize = get_pgsize(iova | paddr, len, &pgcount);
  
-			ops->map(ops, iova, paddr, pgsize, prot, GFP_KERNEL);

-   iova += pgsize;
-   paddr += pgsize;
-   len -= pgsize;
+   ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot,
+  GFP_KERNEL, &mapped);
+   /* Don't get stuck if things have gone wrong */
+   mapped = max(mapped, pgsize);
+   iova += mapped;
+   paddr += mapped;
+   len -= mapped;
}
}
  
@@ -344,15 +352,17 @@ void panfrost_mmu_unmap(struct panfrost_gem_mapping *mapping)

mapping->mmu->as, iova, len);
  
  	while (unmapped_len < len) {

-   size_t unmapped_page;
-   size_t pgsize = get_pgsize(iova, len - unmapped_len);
+   size_t unmapped_page, pgcount;
+   size_t pgsize = get_pgsize(iova, len - unmapped_len, &pgcount);
  
-		if (ops->iova_to_phys(ops, iova)) {

-   unmapped_page = ops->unmap(ops, iova, pgsize, NULL);
-   WARN_ON(unmapped_page != pgsize);
+   if (bo->is_heap)
+   pgcount = 1;
+   if (!bo->is_heap || ops->iova_to_phys(ops, iova)) {
+   unmapped_page = ops->unmap_pages(ops, iova, pgsize, 
pgcount, NULL);
+   WARN_ON(unmapped_page != pgsize * pgcount);


This patch causes this WARN_ON to trigger. It doesn't happen all the
time, I see that the whole unmapped area is mapped. Initially, I thought
that this happens because it tries to unmap a partially mapped range,
but I checked that ops->iova_to_phys() returns address for all 4k chunks.

For example the pgsize * pgcount = 0x800, while returned
unmapped_page = 0x600.

I don't see this problem with this patch reverted. This is using today's
linux-next. Any ideas?


What's the base IOVA in such a case? I'm wondering if the truncated size 
lines up to any interesting boundary. Presumably you're not seeing any 
additional warnings from io-pgtable itself?


Thanks,
Robin.


Re: [PATCH] drm/panfrost: Update io-pgtable API

2022-11-04 Thread Dmitry Osipenko
On 8/23/22 01:01, Robin Murphy wrote:
> Convert to io-pgtable's bulk {map,unmap}_pages() APIs, to help the old
> single-page interfaces eventually go away. Unmapping heap BOs still
> wants to be done a page at a time, but everything else can get the full
> benefit of the more efficient interface.
> 
> Signed-off-by: Robin Murphy 
> ---
>  drivers/gpu/drm/panfrost/panfrost_mmu.c | 40 +++--
>  1 file changed, 25 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
> b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> index b285a8001b1d..e246d914e7f6 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> @@ -248,11 +248,15 @@ void panfrost_mmu_reset(struct panfrost_device *pfdev)
>   mmu_write(pfdev, MMU_INT_MASK, ~0);
>  }
>  
> -static size_t get_pgsize(u64 addr, size_t size)
> +static size_t get_pgsize(u64 addr, size_t size, size_t *count)
>  {
> - if (addr & (SZ_2M - 1) || size < SZ_2M)
> - return SZ_4K;
> + size_t blk_offset = -addr % SZ_2M;
>  
> + if (blk_offset || size < SZ_2M) {
> + *count = min_not_zero(blk_offset, size) / SZ_4K;
> + return SZ_4K;
> + }
> + *count = size / SZ_2M;
>   return SZ_2M;
>  }
>  
> @@ -287,12 +291,16 @@ static int mmu_map_sg(struct panfrost_device *pfdev, 
> struct panfrost_mmu *mmu,
>   dev_dbg(pfdev->dev, "map: as=%d, iova=%llx, paddr=%lx, 
> len=%zx", mmu->as, iova, paddr, len);
>  
>   while (len) {
> - size_t pgsize = get_pgsize(iova | paddr, len);
> + size_t pgcount, mapped = 0;
> + size_t pgsize = get_pgsize(iova | paddr, len, &pgcount);
>  
> - ops->map(ops, iova, paddr, pgsize, prot, GFP_KERNEL);
> - iova += pgsize;
> - paddr += pgsize;
> - len -= pgsize;
> + ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot,
> +GFP_KERNEL, &mapped);
> + /* Don't get stuck if things have gone wrong */
> + mapped = max(mapped, pgsize);
> + iova += mapped;
> + paddr += mapped;
> + len -= mapped;
>   }
>   }
>  
> @@ -344,15 +352,17 @@ void panfrost_mmu_unmap(struct panfrost_gem_mapping 
> *mapping)
>   mapping->mmu->as, iova, len);
>  
>   while (unmapped_len < len) {
> - size_t unmapped_page;
> - size_t pgsize = get_pgsize(iova, len - unmapped_len);
> + size_t unmapped_page, pgcount;
> + size_t pgsize = get_pgsize(iova, len - unmapped_len, &pgcount);
>  
> - if (ops->iova_to_phys(ops, iova)) {
> - unmapped_page = ops->unmap(ops, iova, pgsize, NULL);
> - WARN_ON(unmapped_page != pgsize);
> + if (bo->is_heap)
> + pgcount = 1;
> + if (!bo->is_heap || ops->iova_to_phys(ops, iova)) {
> + unmapped_page = ops->unmap_pages(ops, iova, pgsize, 
> pgcount, NULL);
> + WARN_ON(unmapped_page != pgsize * pgcount);

This patch causes this WARN_ON to trigger. It doesn't happen all the
time, I see that the whole unmapped area is mapped. Initially, I thought
that this happens because it tries to unmap a partially mapped range,
but I checked that ops->iova_to_phys() returns address for all 4k chunks.

For example the pgsize * pgcount = 0x800, while returned
unmapped_page = 0x600.

I don't see this problem with this patch reverted. This is using today's
linux-next. Any ideas?

-- 
Best regards,
Dmitry



Re: [PATCH 07/10] vfio-iommufd: Support iommufd for physical VFIO devices

2022-11-04 Thread Jason Gunthorpe
On Tue, Nov 01, 2022 at 08:21:20AM +, Tian, Kevin wrote:
> > From: Jason Gunthorpe 
> > Sent: Wednesday, October 26, 2022 2:51 AM
> > 
> > +int vfio_iommufd_bind(struct vfio_device *vdev, struct iommufd_ctx *ictx)
> > +{
> > +   u32 ioas_id;
> > +   u32 device_id;
> > +   int ret;
> > +
> > +   lockdep_assert_held(&vdev->dev_set->lock);
> > +
> > +   /*
> > +* If the driver doesn't provide this op then it means the device does
> > +* not do DMA at all. So nothing to do.
> > +*/
> > +   if (!vdev->ops->bind_iommufd)
> > +   return 0;
> 
> Nothing to do or return -EOPNOTSUPP?

As in the other email, nothing to do, driver is "bound" but doesn't
actually need iommufd at all.

> > +   ret = vdev->ops->bind_iommufd(vdev, ictx, &device_id);
> > +   if (ret)
> > +   return ret;
> > +
> > +   if (vdev->ops->attach_ioas) {
> 
> __vfio_register_dev() already verifies that all three callbacks must
> co-exist. Then no need to check it again here and later.

Ok

> > +void vfio_iommufd_unbind(struct vfio_device *vdev)
> > +{
> > +   lockdep_assert_held(&vdev->dev_set->lock);
> > +
> > +   if (!vdev->iommufd_device)
> > +   return;
> 
> there is no iommufd_device in the emulated path...

Yes, this if should just be deleted

Thanks,
Jason


Re: [RFC][PATCH v3 00/33] timers: Use timer_shutdown*() before freeing timers

2022-11-04 Thread Linus Torvalds
On Fri, Nov 4, 2022 at 12:42 PM Steven Rostedt  wrote:
>
> Linus, should I also add any patches that has already been acked by the
> respective maintainer?

No, I'd prefer to keep only the ones that are 100% unambiguously not
changing any semantics.

  Linus


Re: [PATCH 05/10] vfio: Use IOMMU_CAP_ENFORCE_CACHE_COHERENCY for vfio_file_enforced_coherent()

2022-11-04 Thread Jason Gunthorpe
On Thu, Nov 03, 2022 at 04:38:16AM +, Tian, Kevin wrote:
> > From: Jason Gunthorpe 
> > Sent: Tuesday, November 1, 2022 8:26 PM
> > And this:
> > 
> > /*
> >  * If the device does not have
> > IOMMU_CAP_ENFORCE_CACHE_COHERENCY then
> >  * any domain later attached to it will also not support it. If the cap
> >  * is set then the iommu_domain eventually attached to the
> > device/group
> >  * must must use a domain with enforce_cache_coherency().
> >  */
> 
> duplicated 'must'

Done

Jason


Re: [RFC][PATCH v3 00/33] timers: Use timer_shutdown*() before freeing timers

2022-11-04 Thread Steven Rostedt
On Fri, 4 Nov 2022 12:22:32 -0700
Guenter Roeck  wrote:

> Unfortunately the renaming caused some symbol conflicts.
> 
> Global definition: timer_shutdown
> 
>   File Line
> 0 time.c93 static inline void timer_shutdown(struct 
> clock_event_device *evt)
> 1 arm_arch_timer.c 690 static __always_inline int timer_shutdown(const int 
> access,
> 2 timer-fttmr010.c 105 int (*timer_shutdown)(struct clock_event_device *evt);
> 3 timer-sp804.c158 static inline void timer_shutdown(struct 
> clock_event_device *evt)
> 4 timer.h  239 static inline int timer_shutdown(struct timer_list 
> *timer)

$ git grep '\btimer_shutdown'
arch/arm/mach-spear/time.c:static inline void timer_shutdown(struct 
clock_event_device *evt)
arch/arm/mach-spear/time.c: timer_shutdown(evt);
arch/arm/mach-spear/time.c: timer_shutdown(evt);
arch/arm/mach-spear/time.c: timer_shutdown(evt);
drivers/clocksource/arm_arch_timer.c:static __always_inline int 
timer_shutdown(const int access,
drivers/clocksource/arm_arch_timer.c:   return 
timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
drivers/clocksource/arm_arch_timer.c:   return 
timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
drivers/clocksource/arm_arch_timer.c:   return 
timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
drivers/clocksource/arm_arch_timer.c:   return 
timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
drivers/clocksource/timer-fttmr010.c:   int (*timer_shutdown)(struct 
clock_event_device *evt);
drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown(evt);
drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown = 
ast2600_timer_shutdown;
drivers/clocksource/timer-fttmr010.c:   fttmr010->timer_shutdown = 
fttmr010_timer_shutdown;
drivers/clocksource/timer-fttmr010.c:   fttmr010->clkevt.set_state_shutdown = 
fttmr010->timer_shutdown;
drivers/clocksource/timer-fttmr010.c:   fttmr010->clkevt.tick_resume = 
fttmr010->timer_shutdown;
drivers/clocksource/timer-sp804.c:static inline void timer_shutdown(struct 
clock_event_device *evt)
drivers/clocksource/timer-sp804.c:  timer_shutdown(evt);
drivers/clocksource/timer-sp804.c:  timer_shutdown(evt);

Honestly, I think these need to be renamed, as "timer_shutdown()"
should be specific to the timer code, and not individual timers.

I'll start making a patch set that starts by renaming these timers,
then adds the timer_shutdown() API, and finished with the trivial
updates, and that will be a real "PATCH" (non RFC).

Linus, should I also add any patches that has already been acked by the
respective maintainer?

-- Steve


Coverity: kfd_parse_subtype_cache(): Memory - corruptions

2022-11-04 Thread coverity-bot
Hello!

This is an experimental semi-automated report about issues detected by
Coverity from a scan of next-20221104 as part of the linux-next scan project:
https://scan.coverity.com/projects/linux-next-weekly-scan

You're getting this email because you were associated with the identified
lines of code (noted below) that were touched by commits:

  Fri Dec 8 23:08:59 2017 -0500
3a87177eb141 ("drm/amdkfd: Add topology support for dGPUs")

Coverity reported the following:

*** CID 1527133:  Memory - corruptions  (OVERRUN)
drivers/gpu/drm/amd/amdkfd/kfd_crat.c:1113 in kfd_parse_subtype_cache()
1107props->cache_size = cache->cache_size;
1108props->cacheline_size = cache->cache_line_size;
1109props->cachelines_per_tag = 
cache->lines_per_tag;
1110props->cache_assoc = cache->associativity;
props->cache_latency = cache->cache_latency;
1112
vvv CID 1527133:  Memory - corruptions  (OVERRUN)
vvv Overrunning array "cache->sibling_map" of 32 bytes by passing it to a 
function which accesses it at byte offset 63 using argument "64UL". [Note: The 
source code implementation of the function has been overridden by a builtin 
model.]
1113memcpy(props->sibling_map, cache->sibling_map,
1114sizeof(props->sibling_map));
1115
1116/* set the sibling_map_size as 32 for CRAT from 
ACPI */
1117props->sibling_map_size = CRAT_SIBLINGMAP_SIZE;
1118

If this is a false positive, please let us know so we can mark it as
such, or teach the Coverity rules to be smarter. If not, please make
sure fixes get into linux-next. :) For patches fixing this, please
include these lines (but double-check the "Fixes" first):

Reported-by: coverity-bot 
Addresses-Coverity-ID: 1527133 ("Memory - corruptions")
Fixes: 3a87177eb141 ("drm/amdkfd: Add topology support for dGPUs")

I'm not sure why this suddenly appeared after 5 years, but the read
over-run looks legit:

struct crat_subtype_cache {
...
uint8_t sibling_map[CRAT_SIBLINGMAP_SIZE];

#define CRAT_SIBLINGMAP_SIZE32


struct kfd_cache_properties {
...
uint8_t sibling_map[CACHE_SIBLINGMAP_SIZE];

#define CACHE_SIBLINGMAP_SIZE 64

Thanks for your attention!

-- 
Coverity-bot


Re: [RFC][PATCH v3 00/33] timers: Use timer_shutdown*() before freeing timers

2022-11-04 Thread Guenter Roeck
On Fri, Nov 04, 2022 at 01:40:53AM -0400, Steven Rostedt wrote:
> 
> Back in April, I posted an RFC patch set to help mitigate a common issue
> where a timer gets armed just before it is freed, and when the timer
> goes off, it crashes in the timer code without any evidence of who the
> culprit was. I got side tracked and never finished up on that patch set.
> Since this type of crash is still our #1 crash we are seeing in the field,
> it has become a priority again to finish it.
> 
> This is v3 of that patch set. Thomas Gleixner posted an untested version
> that makes timer->function NULL as the flag that it is shutdown. I took that
> code, tested it (fixed it up), added more comments, and changed the
> name to timer_shutdown_sync(). I also converted it to use WARN_ON_ONCE()
> instead of just WARN_ON() as Linus asked for.
> 

Unfortunately the renaming caused some symbol conflicts.

Global definition: timer_shutdown

  File Line
0 time.c93 static inline void timer_shutdown(struct 
clock_event_device *evt)
1 arm_arch_timer.c 690 static __always_inline int timer_shutdown(const int 
access,
2 timer-fttmr010.c 105 int (*timer_shutdown)(struct clock_event_device *evt);
3 timer-sp804.c158 static inline void timer_shutdown(struct 
clock_event_device *evt)
4 timer.h  239 static inline int timer_shutdown(struct timer_list 
*timer)

Guenter


Re: KUnit issues - Was: [igt-dev] [PATCH RFC v2 8/8] drm/i915: check if current->mm is not NULL

2022-11-04 Thread Daniel Latypov
On Fri, Nov 4, 2022 at 12:50 AM Mauro Carvalho Chehab
 wrote:
>
> On Thu, 3 Nov 2022 15:43:26 -0700
> Daniel Latypov  wrote:
>
> > On Thu, Nov 3, 2022 at 8:23 AM Mauro Carvalho Chehab
> >  wrote:
> > >
> > > Hi,
> > >
> > > I'm facing a couple of issues when testing KUnit with the i915 driver.
> > >
> > > The DRM subsystem and the i915 driver has, for a long time, his own
> > > way to do unit tests, which seems to be added before KUnit.
> > >
> > > I'm now checking if it is worth start using KUnit at i915. So, I wrote
> > > a RFC with some patches adding support for the tests we have to be
> > > reported using Kernel TAP and KUnit.
> > >
> > > There are basically 3 groups of tests there:
> > >
> > > - mock tests - check i915 hardware-independent logic;
> > > - live tests - run some hardware-specific tests;
> > > - perf tests - check perf support - also hardware-dependent.
> > >
> > > As they depend on i915 driver, they run only on x86, with PCI
> > > stack enabled, but the mock tests run nicely via qemu.
> > >
> > > The live and perf tests require a real hardware. As we run them
> > > together with our CI, which, among other things, test module
> > > unload/reload and test loading i915 driver with different
> > > modprobe parameters, the KUnit tests should be able to run as
> > > a module.
> > >
> > > While testing KUnit, I noticed a couple of issues:
> > >
> > > 1. kunit.py parser is currently broken when used with modules
> > >
> > > the parser expects "TAP version xx" output, but this won't
> > > happen when loading the kunit test driver.
> > >
> > > Are there any plans or patches fixing this issue?
> >
> > Partially.
> > Note: we need a header to look for so we can strip prefixes (like 
> > timestamps).
> >
> > But there is a patch in the works to add a TAP header for each
> > subtest, hopefully in time for 6.2.
>
> Good to know.
>
> > This is to match the KTAP spec:
> > https://kernel.org/doc/html/latest/dev-tools/ktap.html
>
> I see.
>
> > That should fix it so you can parse one suite's results at a time.
> > I'm pretty sure it won't fix the case where there's multiple suites
> > and/or you're trying to parse all test results at once via
> >
> > $ find /sys/kernel/debug/kunit/ -type f | xargs cat |
> > ./tools/testing/kunit/kunit.py parse
>
> Could you point me to the changeset? perhaps I can write a followup
> patch addressing this case.

rm...@google.com was working on them and should hopefully be able to
send them out real soon.
You should get CC'd on those.

I think the follow-up work is just crafting an example parser input
file and iterating until
  $ ./tools/testing/kunit/kunit.py parse < /tmp/example_input
produces our desired results.

>
> > I think that in-kernel code change + some more python changes could
> > make the above command work, but no one has actively started looking
> > at that just yet.
> > Hopefully we can pick this up and also get it done for 6.2 (unless I'm
> > underestimating how complicated this is).
> >
> > >
> > > 2. current->mm is not initialized
> > >
> > > Some tests do mmap(). They need the mm user context to be initialized,
> > > but this is not happening right now.
> > >
> > > Are there a way to properly initialize it for KUnit?
> >
> > Right, this is a consequence of how early built-in KUnit tests are run
> > after boot.
> > I think for now, the answer is to make the test module-only.
> >
> > I know David had some ideas here, but I can't speak to them.
>
> This is happening when test-i915 is built as module as well.

Oh, I didn't expect that at all.

>
> I suspect that the function which initializes it is mm_alloc() inside
> kernel/fork.c:
>
> struct mm_struct *mm_alloc(void)
> {
> struct mm_struct *mm;
>
> mm = allocate_mm();
> if (!mm)
> return NULL;
>
> memset(mm, 0, sizeof(*mm));
> return mm_init(mm, current, current_user_ns());
> }
>
> As modprobing a test won't fork until all tests run, this never runs.
>
> It seems that the normal usage is at fs/exec.c:
>
> fs/exec.c:  bprm->mm = mm = mm_alloc();
>
> but other places also call it:
>
> arch/arm/mach-rpc/ecard.c:  struct mm_struct * mm = mm_alloc();
> drivers/dma-buf/dma-resv.c: struct mm_struct *mm = mm_alloc();
> include/linux/sched/mm.h:extern struct mm_struct *mm_alloc(void);
> mm/debug_vm_pgtable.c:  args->mm = mm_alloc();
>
> Probably the solution would be to call it inside kunit executor code,
> adding support for modules to use it.

I know basically nothing about the mm code.
I think I vaguely recall there being issues with this on UML or
something, but I could be totally wrong.

I'll wait for David to chime in when he can.

>
> > > 3. there's no test filters for modules
> > >
> > > In order to be able to do proper CI automation, it is needed to
> > > be able to control what tests will run or not. That's specially
> > > int

Re: [PATCH 2/2] drm/i915/mtl: Enable Idle Messaging for GSC CS

2022-11-04 Thread Belgaumkar, Vinay



On 10/31/2022 8:36 PM, Badal Nilawar wrote:

From: Vinay Belgaumkar 

By defaut idle mesaging is disabled for GSC CS so to unblock RC6
entry on media tile idle messaging need to be enabled.

C6 entry instead of RC6. Also *needs*.


Bspec: 71496

Cc: Daniele Ceraolo Spurio 
Signed-off-by: Vinay Belgaumkar 
Signed-off-by: Badal Nilawar 
---
  drivers/gpu/drm/i915/gt/intel_engine_pm.c | 12 
  drivers/gpu/drm/i915/gt/intel_gt_regs.h   |  3 +++
  2 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index b0a4a2dbe3ee..8d391f8fd861 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -15,6 +15,7 @@
  #include "intel_rc6.h"
  #include "intel_ring.h"
  #include "shmem_utils.h"
+#include "intel_gt_regs.h"
  
  static void dbg_poison_ce(struct intel_context *ce)

  {
@@ -271,10 +272,21 @@ static const struct intel_wakeref_ops wf_ops = {
  
  void intel_engine_init__pm(struct intel_engine_cs *engine)

  {
+   struct drm_i915_private *i915 = engine->i915;
struct intel_runtime_pm *rpm = engine->uncore->rpm;
  
  	intel_wakeref_init(&engine->wakeref, rpm, &wf_ops);

intel_engine_init_heartbeat(engine);
+
+   if (IS_METEORLAKE(i915) && engine->id == GSC0) {
+   intel_uncore_write(engine->gt->uncore,
+  RC_PSMI_CTRL_GSCCS,
+  _MASKED_BIT_DISABLE(IDLE_MSG_DISABLE));
+   drm_dbg(&i915->drm,
+   "Set GSC CS Idle Reg to: 0x%x",
+   intel_uncore_read(engine->gt->uncore, 
RC_PSMI_CTRL_GSCCS));

Do we need the debug print here?

+   }
+
  }
  
  /**

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index f4624262dc81..176902a9f2a2 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -908,6 +908,9 @@
  #define  MSG_IDLE_FW_MASK REG_GENMASK(13, 9)
  #define  MSG_IDLE_FW_SHIFT9
  
+#define	RC_PSMI_CTRL_GSCCS	_MMIO(0x11a050)

+#define IDLE_MSG_DISABLE   BIT(0)


Is the alignment off?

Thanks,

Vinay.


+
  #define FORCEWAKE_MEDIA_GEN9  _MMIO(0xa270)
  #define FORCEWAKE_RENDER_GEN9 _MMIO(0xa278)
  


Re: [RFC][PATCH v3 13/33] timers: drm: Use timer_shutdown_sync() before freeing timer

2022-11-04 Thread Steven Rostedt
On Fri, 4 Nov 2022 08:48:28 +
Tvrtko Ursulin  wrote:

> If it stays all DRM drivers in one patch then I guess it needs to go via 
> drm-misc, which for i915 would be okay I think in this case since patch 
> is extremely unlikely to clash with anything. Or split it up per driver 
> and then we can handle it in drm-intel-next once core functionality is in.
> 
> We do however have some more calls to del_timer_sync, where freeing is 
> perhaps not immediately next to the site in code, but things definitely 
> get freed like on module unload. Would we need to convert all of them to 
> avoid some, presumably new, warnings?


I'm happy to split this patch up. I just got a bit lazy and started
just grouping via entire subsystems. You should see the networking
patch ;-)

-- Steve


Re: [PATCH v2 1/2] drm/i915/guc: Properly initialise kernel contexts

2022-11-04 Thread John Harrison

On 11/4/2022 11:53, Ceraolo Spurio, Daniele wrote:

On 11/2/2022 12:21 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

If a context has already been registered prior to first submission
then context init code was not being called. The noticeable effect of
that was the scheduling priority was left at zero (meaning super high
priority) instead of being set to normal. This would occur with
kernel contexts at start of day as they are manually pinned up front
rather than on first submission. So add a call to initialise those
when they are pinned.


Does this need a fixes tag? on one side, we were leaving the priority 
to the wrong value, but on the other there were no actual consequences.


I think that's the point. There was no actual issue, it's just a 
theoretical problem. So there is nothing to be gained by pushing this as 
a fix. It it seems like it would be a lot of unnecessary effort to push 
it all the way back to 5.17.


John.



Reviewed-by: Daniele Ceraolo Spurio 

Daniele


Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c

index 4ccb29f9ac55c..941613be3b9dd 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4111,6 +4111,9 @@ static inline void 
guc_kernel_context_pin(struct intel_guc *guc,

  if (context_guc_id_invalid(ce))
  pin_guc_id(guc, ce);
  +    if (!test_bit(CONTEXT_GUC_INIT, &ce->flags))
+    guc_context_init(ce);
+
  try_context_registration(ce, true);
  }






Re: [RFC][PATCH v3 12/33] timers: dma-buf: Use timer_shutdown_sync() before freeing timer

2022-11-04 Thread Steven Rostedt
On Fri, 4 Nov 2022 08:15:53 +0100
Christian König  wrote:

> > index fb6e0a6ae2c9..5d3e7b503501 100644
> > --- a/drivers/dma-buf/st-dma-fence.c
> > +++ b/drivers/dma-buf/st-dma-fence.c
> > @@ -412,7 +412,7 @@ static int test_wait_timeout(void *arg)
> >   
> > err = 0;
> >   err_free:
> > -   del_timer_sync(&wt.timer);
> > +   timer_shutdown_sync(&wt.timer);  
> 
> Mhm, what exactly is the benefit of renaming the function?
> 
> Not that I'm against the change, but my thinking is more if there are 
> more functions which don't re-arm the time than those which do that then 
> why not forbid it in general?

Timers are more often re-armed then not. I had to look for the
locations where del_timer*() was called just before freeing, and other
locations where they are freed later.

I didn't rename del_timer_sync() to timer_shutdown_sync(), this version
renamed the new "del_timer_shutdown()" to "timer_shutdown_sync()".

Maybe I'm just confused at what you are asking.

-- Steve


[linux-next:master] BUILD SUCCESS WITH WARNING 0cdb3579f1ee4c1e55acf8dfb0697b660067b1f8

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

Warning reports:

https://lore.kernel.org/oe-kbuild-all/202211041320.coq8eelj-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202211041654.zcupre9o-...@intel.com

Warning: (recently discovered and may have been fixed)

drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc.c:4878: warning: This comment 
starts with '/**', but isn't a kernel-doc comment. Refer 
Documentation/doc-guide/kernel-doc.rst
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link_dp.c:5044:24: warning: 
implicit conversion from 'enum ' to 'enum dc_status' 
[-Wenum-conversion]
drivers/gpu/drm/msm/hdmi/hdmi.c:244:1: warning: 'static' is not at beginning of 
declaration [-Wold-style-declaration]
drivers/gpu/drm/msm/hdmi/hdmi.c:251:1: warning: 'static' is not at beginning of 
declaration [-Wold-style-declaration]

Warning ids grouped by kconfigs:

gcc_recent_errors
|-- alpha-allyesconfig
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|   `-- 
drivers-gpu-drm-msm-hdmi-hdmi.c:warning:static-is-not-at-beginning-of-declaration
|-- arc-allyesconfig
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|   `-- 
drivers-gpu-drm-msm-hdmi-hdmi.c:warning:static-is-not-at-beginning-of-declaration
|-- arc-randconfig-r036-20221104
|   `-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|-- arc-randconfig-r043-20221104
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   `-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|-- arm-allyesconfig
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|   `-- 
drivers-gpu-drm-msm-hdmi-hdmi.c:warning:static-is-not-at-beginning-of-declaration
|-- arm-defconfig
|   `-- 
drivers-gpu-drm-msm-hdmi-hdmi.c:warning:static-is-not-at-beginning-of-declaration
|-- arm64-allyesconfig
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|   `-- 
drivers-gpu-drm-msm-hdmi-hdmi.c:warning:static-is-not-at-beginning-of-declaration
|-- i386-allyesconfig
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   `-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|-- ia64-allmodconfig
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   `-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|-- ia64-buildonly-randconfig-r006-20221104
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   `-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|-- m68k-allmodconfig
|   `-- 
drivers-gpu-drm-msm-hdmi-hdmi.c:warning:static-is-not-at-beginning-of-declaration
|-- m68k-allyesconfig
|   `-- 
drivers-gpu-drm-msm-hdmi-hdmi.c:warning:static-is-not-at-beginning-of-declaration
|-- mips-allyesconfig
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|   `-- 
drivers-gpu-drm-msm-hdmi-hdmi.c:warning:static-is-not-at-beginning-o

Re: [PATCH v2 1/2] drm/i915/guc: Properly initialise kernel contexts

2022-11-04 Thread Ceraolo Spurio, Daniele




On 11/2/2022 12:21 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

If a context has already been registered prior to first submission
then context init code was not being called. The noticeable effect of
that was the scheduling priority was left at zero (meaning super high
priority) instead of being set to normal. This would occur with
kernel contexts at start of day as they are manually pinned up front
rather than on first submission. So add a call to initialise those
when they are pinned.


Does this need a fixes tag? on one side, we were leaving the priority to 
the wrong value, but on the other there were no actual consequences.


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 4ccb29f9ac55c..941613be3b9dd 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4111,6 +4111,9 @@ static inline void guc_kernel_context_pin(struct 
intel_guc *guc,
if (context_guc_id_invalid(ce))
pin_guc_id(guc, ce);
  
+	if (!test_bit(CONTEXT_GUC_INIT, &ce->flags))

+   guc_context_init(ce);
+
try_context_registration(ce, true);
  }
  




Re: [PATCH 1/2] drm/radeon: Using unsigned long instead of unsigned to fix possible overflow

2022-11-04 Thread Alex Deucher
On Fri, Nov 4, 2022 at 6:05 AM Hanjun Guo  wrote:
>
> VBIOSImageOffset in struct UEFI_ACPI_VFCT is ULONG (unsigned long),
> but it will be assigned to "unsigned offset", so use unsigned long
> instead of unsigned for the offset, to avoid possible overflow.

ULONG in atombios is 32 bits so an int should be fine.

Alex

>
> Signed-off-by: Hanjun Guo 
> ---
>  drivers/gpu/drm/radeon/radeon_bios.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_bios.c 
> b/drivers/gpu/drm/radeon/radeon_bios.c
> index 3312165..520d1d6 100644
> --- a/drivers/gpu/drm/radeon/radeon_bios.c
> +++ b/drivers/gpu/drm/radeon/radeon_bios.c
> @@ -611,7 +611,7 @@ static bool radeon_acpi_vfct_bios(struct radeon_device 
> *rdev)
> struct acpi_table_header *hdr;
> acpi_size tbl_size;
> UEFI_ACPI_VFCT *vfct;
> -   unsigned offset;
> +   unsigned long offset;
>
> if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
> return false;
> --
> 1.7.12.4
>


Re: [PATCH drm-misc-next v4 0/4] drm/arm/hdlcd: use drm managed resources

2022-11-04 Thread Liviu Dudau
On Wed, Oct 26, 2022 at 05:34:27PM +0200, Danilo Krummrich wrote:
> Hi,

Hi Danilo,

> 
> This patch series converts the driver to use drm managed resources to prevent
> potential use-after-free issues on driver unbind/rebind and to get rid of the
> usage of deprecated APIs.
> 
> Changes in v2:
>   - drop patch "drm/arm/hdlcd: crtc: use drmm_crtc_init_with_planes()"
> 
> Changes in v3:
>   - Fix alternate return paths in srcu read-side critical sections causing a
> stall when unregistering the driver.
>   - Fix potential null pointer dereference in hdlcd_crtc_cleanup() introduced
> dropping the patch in v2.
>   - Add a patch to remove explicit calls to drm_mode_config_cleanup().
> 
> Changes in v4:
>   - Remove patches to protect platform device bound resources with
> drm_dev_{enter,exit}, since this would leave the hardware enabled when
> regularly unloading the driver e.g. via rmmod.
> Instead do this in a later series, once we got drm_dev_unplug() in place
> to deal with a regular driver shutdown.

This series is in a much better shape compared to the existing status quo. rmmod
works without any issue and I can re-insmod the driver again.

The only issue that I'm seeing that is not critical is that at reboot/shutdown 
time
I'm getting an "Unexpected global fault, this could be serious" from the smmu:

[ 6893.467910] arm-smmu 7fb3.iommu: disabling translation
[ 6893.473550] ohci-platform 7ffb.usb: Removing from iommu group 1
[ 6893.479909] ehci-platform 7ffc.usb: Removing from iommu group 1
[ 6893.486931] arm-smmu 7fb1.iommu: disabling translation
[ 6893.492521] hdlcd 7ff5.hdlcd: Removing from iommu group 3
[ 6893.492650] arm-smmu 7fb1.iommu: Unexpected global fault, this could be 
serious
[ 6893.505959] arm-smmu 7fb1.iommu: GFSR 0x8001, GFSYNR0 
0x, GFSYNR1 0x, GFSYNR2 0x
[ 6893.516511] arm-smmu 7fb0.iommu: disabling translation
[ 6893.522195] dma-pl330 7ff0.dma-controller: Removing from iommu group 2
[ 6893.529607] arm-smmu 2b50.iommu: disabling translation
[ 6893.535221] pcieport :00:00.0: Removing from iommu group 0
[ 6893.541135] pci :01:00.0: Removing from iommu group 0
[ 6893.546604] pcieport :02:01.0: Removing from iommu group 0
[ 6893.552511] pcieport :02:02.0: Removing from iommu group 0
[ 6893.558418] pcieport :02:03.0: Removing from iommu group 0
[ 6893.564329] pcieport :02:0c.0: Removing from iommu group 0
[ 6893.570393] pcieport :02:10.0: Removing from iommu group 0
[ 6893.576314] pcieport :02:1f.0: Removing from iommu group 0
[ 6893.582214] sata_sil24 :03:00.0: Removing from iommu group 0
[ 6893.588270] sky2 :08:00.0: Removing from iommu group 0
[ 6893.594616] reboot: Power down


The reboot/shutdown succeeds, so I'm not too worried about it for now, but hope 
that
this is something you'll keep in mind in the later series when you do 
drm_dev_unplug().

With that, for the whole series:

Acked-by: Liviu Dudau 

Thanks for the patience and going through the series iterations with me.

I can pull this series into drm-misc-next on Monday if you don't have any other 
plans.

Best regards,
Liviu

> 
> Danilo Krummrich (4):
>   drm/arm/hdlcd: use drmm_* to allocate driver structures
>   drm/arm/hdlcd: replace drm->dev_private with drm_to_hdlcd_priv()
>   drm/arm/hdlcd: plane: use drm managed resources
>   drm/arm/hdlcd: remove calls to drm_mode_config_cleanup()
> 
>  drivers/gpu/drm/arm/hdlcd_crtc.c | 24 +++
>  drivers/gpu/drm/arm/hdlcd_drv.c  | 41 
>  drivers/gpu/drm/arm/hdlcd_drv.h  |  2 ++
>  3 files changed, 32 insertions(+), 35 deletions(-)
> 
> 
> base-commit: e1e7bc481d49c3e3ada11029ce0d9b85a0a539d7
> -- 
> 2.37.3
> 

-- 

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


Re: [PATCH v3 3/8] dt-bindings: display/msm: add support for the display on SM8450

2022-11-04 Thread Rob Herring


On Fri, 04 Nov 2022 16:03:19 +0300, Dmitry Baryshkov wrote:
> Add DPU and MDSS schemas to describe MDSS and DPU blocks on the Qualcomm
> SM8450 platform.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../bindings/display/msm/qcom,sm8450-dpu.yaml | 132 +++
>  .../display/msm/qcom,sm8450-mdss.yaml | 347 ++
>  2 files changed, 479 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/qcom,sm8450-dpu.yaml
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/qcom,sm8450-mdss.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
./Documentation/devicetree/bindings/display/msm/qcom,sm8450-mdss.yaml: Unable 
to find schema file matching $id: 
http://devicetree.org/schemas/display/msm/mdss-common.yaml
./Documentation/devicetree/bindings/display/msm/qcom,sm8450-dpu.yaml: Unable to 
find schema file matching $id: 
http://devicetree.org/schemas/display/msm/dpu-common.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/qcom,sm8450-dpu.example.dtb:
 display-controller@ae01000: False schema does not allow {'compatible': 
['qcom,sm8450-dpu'], 'reg': [[182456320, 585728], [183173120, 8200]], 
'reg-names': ['mdp', 'vbif'], 'clocks': [[4294967295, 28], [4294967295, 29], 
[4294967295, 1], [4294967295, 63], [4294967295, 60], [4294967295, 75]], 
'clock-names': ['bus', 'nrt_bus', 'iface', 'lut', 'core', 'vsync'], 
'assigned-clocks': [[4294967295, 75]], 'assigned-clock-rates': [[1920]], 
'operating-points-v2': [[1]], 'power-domains': [[4294967295, 6]], 'interrupts': 
[[0]], 'ports': {'#address-cells': [[1]], '#size-cells': [[0]], 'port@0': 
{'reg': [[0]], 'endpoint': {'remote-endpoint': [[4294967295]]}}, 'port@1': 
{'reg': [[1]], 'endpoint': {'remote-endpoint': [[4294967295]]}}}, 'opp-table': 
{'compatible': ['operating-points-v2'], 'phandle': [[1]], 'opp-17200': 
{'opp-hz': [[0], [17200]], 'required-opps': [[4294967295]]}, 'o
 pp-2': {'opp-hz': [[0], [2]], 'required-opps': 
[[4294967295]]}, 'opp-32500': {'opp-hz': [[0], [32500]], 
'required-opps': [[4294967295]]}, 'opp-37500': {'opp-hz': [[0], 
[37500]], 'required-opps': [[4294967295]]}, 'opp-5': {'opp-hz': 
[[0], [5]], 'required-opps': [[4294967295]]}}, '$nodename': 
['display-controller@ae01000']}
From schema: 
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/qcom,sm8450-dpu.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/qcom,sm8450-dpu.example.dtb:
 display-controller@ae01000: Unevaluated properties are not allowed 
('interrupts', 'operating-points-v2', 'opp-table', 'ports', 'power-domains' 
were unexpected)
From schema: 
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/qcom,sm8450-dpu.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/qcom,sm8450-mdss.example.dtb:
 display-subsystem@ae0: False schema does not allow {'compatible': 
['qcom,sm8450-mdss'], 'reg': [[182452224, 4096]], 'reg-names': ['mdss'], 
'interconnects': [[4294967295, 14, 0, 4294967295, 3, 0], [4294967295, 14, 0, 
4294967295, 3, 0]], 'interconnect-names': ['mdp0-mem', 'mdp1-mem'], 'resets': 
[[4294967295, 0]], 'power-domains': [[4294967295, 0]], 'clocks': [[4294967295, 
1], [4294967295, 28], [4294967295, 29], [4294967295, 60]], 'clock-names': 
['iface', 'bus', 'nrt_bus', 'core'], 'interrupts': [[0, 83, 4]], 
'interrupt-controller': True, '#interrupt-cells': [[1]], 'iommus': 
[[4294967295, 10240, 1026]], '#address-cells': [[1]], '#size-cells': [[1]], 
'ranges': True, 'display-controller@ae01000': {'compatible': 
['qcom,sm8450-dpu'], 'reg': [[182456320, 585728], [183173120, 8200]], 
'reg-names': ['mdp', 'vbif'], 'clocks': [[4294967295, 28], [4294967295, 29], 
[4294967295, 1], 
 [4294967295, 63], [4294967295, 60], [4294967295, 75]], 'clock-names': ['bus', 
'nrt_bus', 'iface', 'lut', 'core', 'vsync'], 'assigned-clocks': [[4294967295, 
75]], 'assigned-clock-rates': [[1920]], 'operating-points-v2': [[1]], 
'power-domains': [[4294967295, 6]], 'interrupts': [[0]], 'ports': 
{'#address-cells': [[1]], '#size-cells': [[0]], 'port@0': {'reg': [[0]], 
'endpoint': {'remote-endpoint': [[2]], 'phandle': [[6]]}}, 'port@1': {'reg': 
[[1]], 'endpoint': {'remote-endpoint': [[3]], 'phandle': [[8]]}}}, 'opp-table': 
{'compatible': ['operating-points-v2'], 'phandle': [[1]], 'opp-17200': 
{'opp-hz': [[0], [17200]], 'required-opps': [[4294967295]]}, 
'opp-2': {'opp-hz': [[0], [2]], 'required-opps': 
[[4294967295]]}, 'opp-32500': {'opp-hz': [[0], [32500]], 
'required-opps': [[4294967295]]}, 'opp-37500': {'opp-hz': [[0], 
[37500]], 'required-opps': [[4294967295]]}, 'opp-5': {'opp-hz': 
[[0], [5]], 'requi

Re: [PATCH v2] drm/i915/mtl: Add Wa_14017073508 for SAMedia

2022-11-04 Thread Rodrigo Vivi


On Fri, Nov 04, 2022 at 12:15:59AM +0530, Badal Nilawar wrote:
> This workaround is added for Media tile of MTL A step. It is to help
> pcode workaround which handles the hardware issue seen during package C2/C3
> transitions due to RC6 entry/exit transitions on Media tile. As a part of
> workaround pcode expect kmd to send mailbox message "media busy" when
> components of Media tile are in use and "media idle" otherwise.
> As per workaround description gucrc need to be disabled so enabled
> host based RC for Media tile.
> 
> v2:
>  - Correct workaround id (Matt)
>  - Fix review comments (Rodrigo)
> 
> Cc: Rodrigo Vivi 
> Cc: Radhakrishna Sripada 
> Cc: Vinay Belgaumkar 
> Cc: Chris Wilson 
> Signed-off-by: Badal Nilawar 

Reviewed-by: Rodrigo Vivi 
> ---
>  drivers/gpu/drm/i915/gt/intel_gt_pm.c | 27 +++
>  drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c | 13 ++-
>  drivers/gpu/drm/i915/i915_drv.h   |  4 
>  drivers/gpu/drm/i915/i915_reg.h   |  9 
>  4 files changed, 52 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
> b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
> index f553e2173bda..833b7682643f 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
> @@ -19,10 +19,31 @@
>  #include "intel_rc6.h"
>  #include "intel_rps.h"
>  #include "intel_wakeref.h"
> +#include "intel_pcode.h"
>  #include "pxp/intel_pxp_pm.h"
>  
>  #define I915_GT_SUSPEND_IDLE_TIMEOUT (HZ / 2)
>  
> +static void mtl_media_busy(struct intel_gt *gt)
> +{
> + /* Wa_14017073508: mtl */
> + if (IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0) &&
> + gt->type == GT_MEDIA)
> + snb_pcode_write_p(gt->uncore, PCODE_MBOX_GT_STATE,
> +   PCODE_MBOX_GT_STATE_MEDIA_BUSY,
> +   PCODE_MBOX_GT_STATE_DOMAIN_MEDIA, 0);
> +}
> +
> +static void mtl_media_idle(struct intel_gt *gt)
> +{
> + /* Wa_14017073508: mtl */
> + if (IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0) &&
> + gt->type == GT_MEDIA)
> + snb_pcode_write_p(gt->uncore, PCODE_MBOX_GT_STATE,
> +   PCODE_MBOX_GT_STATE_MEDIA_NOT_BUSY,
> +   PCODE_MBOX_GT_STATE_DOMAIN_MEDIA, 0);
> +}
> +
>  static void user_forcewake(struct intel_gt *gt, bool suspend)
>  {
>   int count = atomic_read(>->user_wakeref);
> @@ -70,6 +91,9 @@ static int __gt_unpark(struct intel_wakeref *wf)
>  
>   GT_TRACE(gt, "\n");
>  
> + /* Wa_14017073508: mtl */
> + mtl_media_busy(gt);
> +
>   /*
>* It seems that the DMC likes to transition between the DC states a lot
>* when there are no connected displays (no active power domains) during
> @@ -119,6 +143,9 @@ static int __gt_park(struct intel_wakeref *wf)
>   GEM_BUG_ON(!wakeref);
>   intel_display_power_put_async(i915, POWER_DOMAIN_GT_IRQ, wakeref);
>  
> + /* Wa_14017073508: mtl */
> + mtl_media_idle(gt);
> +
>   return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
> index 8f8dd05835c5..b5855091cf6a 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
> @@ -11,9 +11,20 @@
>  
>  static bool __guc_rc_supported(struct intel_guc *guc)
>  {
> + struct intel_gt *gt = guc_to_gt(guc);
> +
> + /*
> +  * Wa_14017073508: mtl
> +  * Do not enable gucrc to avoid additional interrupts which
> +  * may disrupt pcode wa.
> +  */
> + if (IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0) &&
> + gt->type == GT_MEDIA)
> + return false;
> +
>   /* GuC RC is unavailable for pre-Gen12 */
>   return guc->submission_supported &&
> - GRAPHICS_VER(guc_to_gt(guc)->i915) >= 12;
> + GRAPHICS_VER(gt->i915) >= 12;
>  }
>  
>  static bool __guc_rc_selected(struct intel_guc *guc)
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 05b3300cc4ed..659b92382ff2 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -740,6 +740,10 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>  #define IS_XEHPSDV_GRAPHICS_STEP(__i915, since, until) \
>   (IS_XEHPSDV(__i915) && IS_GRAPHICS_STEP(__i915, since, until))
>  
> +#define IS_MTL_GRAPHICS_STEP(__i915, variant, since, until) \
> + (IS_SUBPLATFORM(__i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_##variant) 
> && \
> +  IS_GRAPHICS_STEP(__i915, since, until))
> +
>  /*
>   * DG2 hardware steppings are a bit unusual.  The hardware design was forked 
> to
>   * create three variants (G10, G11, and G12) which each have distinct
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 765a10e0de88..23d732413919 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @

Re: [Intel-gfx] [PATCH] drm/i915: Don't wait forever in drop_caches

2022-11-04 Thread John Harrison

On 11/4/2022 03:01, Tvrtko Ursulin wrote:

On 03/11/2022 19:16, John Harrison wrote:

On 11/3/2022 02:38, Tvrtko Ursulin wrote:

On 03/11/2022 09:18, Tvrtko Ursulin wrote:

On 03/11/2022 01:33, John Harrison wrote:

On 11/2/2022 07:20, Tvrtko Ursulin wrote:

On 02/11/2022 12:12, Jani Nikula wrote:

On Tue, 01 Nov 2022, john.c.harri...@intel.com wrote:

From: John Harrison 

At the end of each test, IGT does a drop caches call via sysfs 
with


sysfs?
Sorry, that was meant to say debugfs. I've also been working on 
some sysfs IGT issues and evidently got my wires crossed!




special flags set. One of the possible paths waits for idle 
with an
infinite timeout. That causes problems for debugging issues 
when CI
catches a "can't go idle" test failure. Best case, the CI 
system times

out (after 90s), attempts a bunch of state dump actions and then
reboots the system to recover it. Worst case, the CI system 
can't do
anything at all and then times out (after 1000s) and simply 
reboots.
Sometimes a serial port log of dmesg might be available, 
sometimes not.


So rather than making life hard for ourselves, change the 
timeout to

be 10s rather than infinite. Also, trigger the standard
wedge/reset/recover sequence so that testing can continue with a
working system (if possible).

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/i915_debugfs.c | 7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c

index ae987e92251dd..9d916fbbfc27c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -641,6 +641,9 @@ 
DEFINE_SIMPLE_ATTRIBUTE(i915_perf_noa_delay_fops,

    DROP_RESET_ACTIVE | \
    DROP_RESET_SEQNO | \
    DROP_RCU)
+
+#define DROP_IDLE_TIMEOUT    (HZ * 10)


I915_IDLE_ENGINES_TIMEOUT is defined in i915_drv.h. It's also 
only used

here.


So move here, dropping i915 prefix, next to the newly proposed one?

Sure, can do that.




I915_GEM_IDLE_TIMEOUT is defined in i915_gem.h. It's only used in
gt/intel_gt.c.


Move there and rename to GT_IDLE_TIMEOUT?

I915_GT_SUSPEND_IDLE_TIMEOUT is defined and used only in 
intel_gt_pm.c.


No action needed, maybe drop i915 prefix if wanted.

These two are totally unrelated and in code not being touched by 
this change. I would rather not conflate changing random other 
things with fixing this specific issue.



I915_IDLE_ENGINES_TIMEOUT is in ms, the rest are in jiffies.


Add _MS suffix if wanted.


My head spins.


I follow and raise that the newly proposed DROP_IDLE_TIMEOUT 
applies to DROP_ACTIVE and not only DROP_IDLE.
My original intention for the name was that is the 'drop caches 
timeout for intel_gt_wait_for_idle'. Which is quite the mouthful 
and hence abbreviated to DROP_IDLE_TIMEOUT. But yes, I realised 
later that name can be conflated with the DROP_IDLE flag. Will 
rename.





Things get refactored, code moves around, bits get left behind, 
who knows. No reason to get too worked up. :) As long as people 
are taking a wider view when touching the code base, and are not 
afraid to send cleanups, things should be good.
On the other hand, if every patch gets blocked in code review 
because someone points out some completely unrelated piece of code 
could be a bit better then nothing ever gets fixed. If you spot 
something that you think should be improved, isn't the general 
idea that you should post a patch yourself to improve it?


There's two maintainers per branch and an order of magnitude or two 
more developers so it'd be nice if cleanups would just be incoming 
on self-initiative basis. ;)


For the actual functional change at hand - it would be nice if 
code paths in question could handle SIGINT and then we could punt 
the decision on how long someone wants to wait purely to 
userspace. But it's probably hard and it's only debugfs so whatever.


The code paths in question will already abort on a signal won't 
they? Both intel_gt_wait_for_idle() and 
intel_guc_wait_for_pending_msg(), which is where the 
uc_wait_for_idle eventually ends up, have an 'if(signal_pending) 
return -EINTR;' check. Beyond that, it sounds like what you are 
asking for is a change in the IGT libraries and/or CI framework to 
start sending signals after some specific timeout. That seems like 
a significantly more complex change (in terms of the number of 
entities affected and number of groups involved) and unnecessary.


If you say so, I haven't looked at them all. But if the code path 
in question already aborts on signals then I am not sure what is 
the patch fixing? I assumed you are trying to avoid the write stuck 
in D forever, which then prevents driver unload and everything, 
requiring the test runner to eventually reboot. If you say SIGINT 
works then you can already recover from userspace, no?


Whether or not 10s is enough CI will hopefully tell us. I'd 
probably err on the side of safety and make it longer,

Re: [PATCH RESEND 00/13] Convert omapfb drivers to gpiod API

2022-11-04 Thread Helge Deller

On 11/4/22 04:16, Dmitry Torokhov wrote:

This series converts various OMAPFB drivers to use the newer gpiod API
that respects line polarity specified in DTS.

Unfortunately existing DTS files specify incorrect (active high) polarity
for reset lines. As discussed in [1] we will not try to correct existing
DTSes, but instead follow the path established by DRM drivers for the same
components, and continue using inverted polarity in the FB drivers.

[1] 
https://lore.kernel.org/all/20221004213503.848262-1-dmitry.torok...@gmail.com/

To: Helge Deller 
To: Tony Lindgren 
To: Tomi Valkeinen 
To: Sebastian Reichel 
Cc: linux-o...@vger.kernel.org
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org

---
Dmitry Torokhov (13):
   omapfb: connector-hdmi: switch to using gpiod API
   omapfb: panel-sony-acx565akm: remove support for platform data
   omapfb: panel-sony-acx565akm: switch to using gpiod API
   omapfb: encoder-tfp410: switch to using gpiod API
   omapfb: panel-dsi-cm: switch to using gpiod API
   omapfb: panel-tpo-td043mtea1: switch to using gpiod API
   omapfb: panel-nec-nl8048hl11: switch to using gpiod API
   omapfb: panel-dpi: remove support for platform data
   omapfb: connector-analog-tv: remove support for platform data
   omapfb: encoder-opa362: fix included headers
   omapfb: panel-lgphilips-lb035q02: remove backlight GPIO handling
   omapfb: panel-tpo-td028ttec1: stop including gpio.h
   omapfb: panel-sharp-ls037v7dw01: fix included headers

  .../omap2/omapfb/displays/connector-analog-tv.c|  60 ++-
  .../fbdev/omap2/omapfb/displays/connector-hdmi.c   |  49 +++--
  .../fbdev/omap2/omapfb/displays/encoder-opa362.c   |   4 +-
  .../fbdev/omap2/omapfb/displays/encoder-tfp410.c   |  67 
  .../video/fbdev/omap2/omapfb/displays/panel-dpi.c  |  83 ++-
  .../fbdev/omap2/omapfb/displays/panel-dsi-cm.c | 116 -
  .../omapfb/displays/panel-lgphilips-lb035q02.c |  21 +---
  .../omap2/omapfb/displays/panel-nec-nl8048hl11.c   |  72 -
  .../omapfb/displays/panel-sharp-ls037v7dw01.c  |   3 +-
  .../omap2/omapfb/displays/panel-sony-acx565akm.c   | 105 ++-
  .../omap2/omapfb/displays/panel-tpo-td028ttec1.c   |   1 -
  .../omap2/omapfb/displays/panel-tpo-td043mtea1.c   |  59 +++
  include/video/omap-panel-data.h|  71 -
  13 files changed, 170 insertions(+), 541 deletions(-)
---
base-commit: 61c3426aca2c71052ddcd06c32e29d92304990fd
change-id: 20221103-omapfb-gpiod-87ca2550bd90


series applied to fbdev git tree.

Thanks!
Helge



Re: [PATCH v2 5/5] drm/i915/mtl: don't expose GSC command streamer to the user

2022-11-04 Thread Matt Roper
On Wed, Nov 02, 2022 at 10:10:47AM -0700, Daniele Ceraolo Spurio wrote:
> There is no userspace user for this CS yet, we only need it for internal
> kernel ops (e.g. HuC, PXP), so don't expose it.
> 
> v2: even if it's not exposed, rename the engine so it is easier to
> identify in the debug logs (Matt)
> 
> Signed-off-by: Daniele Ceraolo Spurio 
> Cc: Matt Roper 

Reviewed-by: Matt Roper 

> ---
>  drivers/gpu/drm/i915/gt/intel_engine_user.c | 27 -
>  1 file changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
> b/drivers/gpu/drm/i915/gt/intel_engine_user.c
> index 79312b734690..cd4f1b126f75 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
> @@ -191,6 +191,15 @@ static void add_legacy_ring(struct legacy_ring *ring,
>   ring->instance++;
>  }
>  
> +static void engine_rename(struct intel_engine_cs *engine, const char *name, 
> u16 instance)
> +{
> + char old[sizeof(engine->name)];
> +
> + memcpy(old, engine->name, sizeof(engine->name));
> + scnprintf(engine->name, sizeof(engine->name), "%s%u", name, instance);
> + drm_dbg(&engine->i915->drm, "renamed %s to %s\n", old, engine->name);
> +}
> +
>  void intel_engines_driver_register(struct drm_i915_private *i915)
>  {
>   struct legacy_ring ring = {};
> @@ -206,11 +215,19 @@ void intel_engines_driver_register(struct 
> drm_i915_private *i915)
>   struct intel_engine_cs *engine =
>   container_of((struct rb_node *)it, typeof(*engine),
>uabi_node);
> - char old[sizeof(engine->name)];
>  
>   if (intel_gt_has_unrecoverable_error(engine->gt))
>   continue; /* ignore incomplete engines */
>  
> + /*
> +  * We don't want to expose the GSC engine to the users, but we
> +  * still rename it so it is easier to identify in the debug logs
> +  */
> + if (engine->id == GSC0) {
> + engine_rename(engine, "gsc", 0);
> + continue;
> + }
> +
>   GEM_BUG_ON(engine->class >= ARRAY_SIZE(uabi_classes));
>   engine->uabi_class = uabi_classes[engine->class];
>  
> @@ -220,11 +237,9 @@ void intel_engines_driver_register(struct 
> drm_i915_private *i915)
>   i915->engine_uabi_class_count[engine->uabi_class]++;
>  
>   /* Replace the internal name with the final user facing name */
> - memcpy(old, engine->name, sizeof(engine->name));
> - scnprintf(engine->name, sizeof(engine->name), "%s%u",
> -   intel_engine_class_repr(engine->class),
> -   engine->uabi_instance);
> - DRM_DEBUG_DRIVER("renamed %s to %s\n", old, engine->name);
> + engine_rename(engine,
> +   intel_engine_class_repr(engine->class),
> +   engine->uabi_instance);
>  
>   rb_link_node(&engine->uabi_node, prev, p);
>   rb_insert_color(&engine->uabi_node, &i915->uabi_engines);
> -- 
> 2.37.3
> 

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation


[PATCH 0/2] Add GT oriented dmesg output

2022-11-04 Thread John . C . Harrison
From: John Harrison 

When trying to analyse bug reports from CI, customers, etc. it can be
difficult to work out exactly what is happening on which GT in a
multi-GT system. So add GT oriented debug/error message wrappers. If
used instead of the drm_ equivalents, you get the same output but with
a GT# prefix on it.

This patch also updates the gt/uc files to use the new helpers as a
first step. The intention would be to convert all output messages that
have access to a GT structure.

Signed-off-by: John Harrison 


John Harrison (2):
  drm/i915/gt: Add GT oriented dmesg output
  drm/i915/uc: Update the gt/uc code to use GT_ERR and friends

 drivers/gpu/drm/i915/gt/intel_gt.h| 15 +++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c| 25 +++--
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c|  9 +-
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 50 --
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  9 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 17 ++--
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c| 49 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c |  3 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   |  6 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 56 ++--
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 20 ++--
 drivers/gpu/drm/i915/gt/uc/intel_uc.c | 84 -
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 91 +--
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 36 
 .../drm/i915/gt/uc/selftest_guc_hangcheck.c   | 22 ++---
 .../drm/i915/gt/uc/selftest_guc_multi_lrc.c   | 10 +-
 16 files changed, 243 insertions(+), 259 deletions(-)

-- 
2.37.3



[PATCH 2/2] drm/i915/uc: Update the gt/uc code to use GT_ERR and friends

2022-11-04 Thread John . C . Harrison
From: John Harrison 

Use the new GT oriented output message helpers where possible.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c| 25 +++--
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c|  9 +-
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 50 --
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  9 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 17 ++--
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c| 49 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c |  3 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   |  6 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 56 ++--
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 20 ++--
 drivers/gpu/drm/i915/gt/uc/intel_uc.c | 84 -
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 91 +--
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 36 
 .../drm/i915/gt/uc/selftest_guc_hangcheck.c   | 22 ++---
 .../drm/i915/gt/uc/selftest_guc_multi_lrc.c   | 10 +-
 15 files changed, 228 insertions(+), 259 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 27b09ba1d295f..36983a2cc20e8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -330,7 +330,7 @@ static void guc_init_params(struct intel_guc *guc)
params[GUC_CTL_DEVID] = guc_ctl_devid(guc);
 
for (i = 0; i < GUC_CTL_MAX_DWORDS; i++)
-   DRM_DEBUG_DRIVER("param[%2d] = %#x\n", i, params[i]);
+   GT_DBG(guc_to_gt(guc), "param[%2d] = %#x\n", i, params[i]);
 }
 
 /*
@@ -475,8 +475,8 @@ void intel_guc_fini(struct intel_guc *guc)
 int intel_guc_send_mmio(struct intel_guc *guc, const u32 *request, u32 len,
u32 *response_buf, u32 response_buf_size)
 {
-   struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
-   struct intel_uncore *uncore = guc_to_gt(guc)->uncore;
+   struct intel_gt *gt = guc_to_gt(guc);
+   struct intel_uncore *uncore = gt->uncore;
u32 header;
int i;
int ret;
@@ -510,8 +510,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*request, u32 len,
   10, 10, &header);
if (unlikely(ret)) {
 timeout:
-   drm_err(&i915->drm, "mmio request %#x: no reply %x\n",
-   request[0], header);
+   GT_ERR(gt, "mmio request %#x: no reply %x\n", request[0], 
header);
goto out;
}
 
@@ -532,8 +531,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*request, u32 len,
if (FIELD_GET(GUC_HXG_MSG_0_TYPE, header) == 
GUC_HXG_TYPE_NO_RESPONSE_RETRY) {
u32 reason = FIELD_GET(GUC_HXG_RETRY_MSG_0_REASON, header);
 
-   drm_dbg(&i915->drm, "mmio request %#x: retrying, reason %u\n",
-   request[0], reason);
+   GT_DBG(gt, "mmio request %#x: retrying, reason %u\n", 
request[0], reason);
goto retry;
}
 
@@ -541,16 +539,14 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*request, u32 len,
u32 hint = FIELD_GET(GUC_HXG_FAILURE_MSG_0_HINT, header);
u32 error = FIELD_GET(GUC_HXG_FAILURE_MSG_0_ERROR, header);
 
-   drm_err(&i915->drm, "mmio request %#x: failure %x/%u\n",
-   request[0], error, hint);
+   GT_ERR(gt, "mmio request %#x: failure %x/%u\n", request[0], 
error, hint);
ret = -ENXIO;
goto out;
}
 
if (FIELD_GET(GUC_HXG_MSG_0_TYPE, header) != 
GUC_HXG_TYPE_RESPONSE_SUCCESS) {
 proto:
-   drm_err(&i915->drm, "mmio request %#x: unexpected reply %#x\n",
-   request[0], header);
+   GT_ERR(gt, "mmio request %#x: unexpected reply %#x\n", 
request[0], header);
ret = -EPROTO;
goto out;
}
@@ -592,9 +588,9 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc 
*guc,
msg = payload[0] & guc->msg_enabled_mask;
 
if (msg & INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)
-   drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC crash 
dump notification!\n");
+   GT_ERR(guc_to_gt(guc), "Received early GuC crash dump 
notification!\n");
if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
-   drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC 
exception notification!\n");
+   GT_ERR(guc_to_gt(guc), "Received early GuC exception 
notification!\n");
 
return 0;
 }
@@ -648,7 +644,8 @@ int intel_guc_suspend(struct intel_guc *guc)
 */
ret = intel_guc_send_mmio(guc, action, ARRAY_SIZE(action), 
NULL, 0);
if (ret)
-   DRM_ERROR("GuC suspend: RESET_CLIENT action failed with 
error %d!\n", ret);
+   GT_ERR(guc_to_gt(guc),
+  

[PATCH 1/2] drm/i915/gt: Add GT oriented dmesg output

2022-11-04 Thread John . C . Harrison
From: John Harrison 

When trying to analyse bug reports from CI, customers, etc. it can be
difficult to work out exactly what is happening on which GT in a
multi-GT system. So add GT oriented debug/error message wrappers. If
used instead of the drm_ equivalents, you get the same output but with
a GT# prefix on it.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_gt.h | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
b/drivers/gpu/drm/i915/gt/intel_gt.h
index e0365d5562484..1e016fb0117a4 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -13,6 +13,21 @@
 struct drm_i915_private;
 struct drm_printer;
 
+#define GT_ERR(_gt, _fmt, ...) \
+   drm_err(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__)
+
+#define GT_WARN(_gt, _fmt, ...) \
+   drm_warn(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, 
##__VA_ARGS__)
+
+#define GT_NOTICE(_gt, _fmt, ...) \
+   drm_notice(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, 
##__VA_ARGS__)
+
+#define GT_INFO(_gt, _fmt, ...) \
+   drm_info(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, 
##__VA_ARGS__)
+
+#define GT_DBG(_gt, _fmt, ...) \
+   drm_dbg(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__)
+
 #define GT_TRACE(gt, fmt, ...) do {\
const struct intel_gt *gt__ __maybe_unused = (gt);  \
GEM_TRACE("%s " fmt, dev_name(gt__->i915->drm.dev), \
-- 
2.37.3



Re: [PATCH v2 22/65] clk: davinci: da8xx-cfgchip: Add a determine_rate hook

2022-11-04 Thread David Lechner

On 11/4/22 8:17 AM, Maxime Ripard wrote:

The Davinci DA8xxx cfgchip "clk48" clock implements a mux with a
set_parent hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The latter case would be equivalent to setting the flag
CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook
to __clk_mux_determine_rate(). Indeed, if no determine_rate
implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise. __clk_mux_determine_rate() has the exact same behavior when
CLK_SET_RATE_NO_REPARENT is set.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.


The parent is defined in the device tree and is not expected to change
at runtime, so if I am understanding the patch correctly, setting the
CLK_SET_RATE_NO_REPARENT flag seems correct.



Signed-off-by: Maxime Ripard 
---
  drivers/clk/davinci/da8xx-cfgchip.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/clk/davinci/da8xx-cfgchip.c 
b/drivers/clk/davinci/da8xx-cfgchip.c
index c04276bc4051..4c1cc59bba53 100644
--- a/drivers/clk/davinci/da8xx-cfgchip.c
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -565,6 +565,7 @@ static u8 da8xx_usb1_clk48_get_parent(struct clk_hw *hw)
  }
  
  static const struct clk_ops da8xx_usb1_clk48_ops = {

+   .determine_rate = __clk_mux_determine_rate,
.set_parent = da8xx_usb1_clk48_set_parent,
.get_parent = da8xx_usb1_clk48_get_parent,
  };
@@ -589,6 +590,7 @@ da8xx_cfgchip_register_usb1_clk48(struct device *dev,
  
  	init.name = "usb1_clk48";

init.ops = &da8xx_usb1_clk48_ops;
+   init.flags = CLK_SET_RATE_NO_REPARENT;
init.parent_names = parent_names;
init.num_parents = 2;
  





Re: [PATCH v2 54/65] clk: da8xx: clk48: Switch to determine_rate

2022-11-04 Thread David Lechner

On 11/4/22 8:18 AM, Maxime Ripard wrote:

The TI DA8xx USB0 clk48 clocks implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.


I think this one should be the same as the clk:davinci changes and
not allow re-parenting. Since this is a USB 48MHz PHY clock, a rate
change will never be requested.



Signed-off-by: Maxime Ripard 
---
  drivers/clk/davinci/da8xx-cfgchip.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/davinci/da8xx-cfgchip.c 
b/drivers/clk/davinci/da8xx-cfgchip.c
index 4c1cc59bba53..f60c97091818 100644
--- a/drivers/clk/davinci/da8xx-cfgchip.c
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -462,10 +462,12 @@ static unsigned long da8xx_usb0_clk48_recalc_rate(struct 
clk_hw *hw,
return 4800;
  }
  
-static long da8xx_usb0_clk48_round_rate(struct clk_hw *hw, unsigned long rate,

-   unsigned long *parent_rate)
+static int da8xx_usb0_clk48_determine_rate(struct clk_hw *hw,
+  struct clk_rate_request *req)
  {
-   return 4800;
+   req->rate = 4800;
+
+   return 0;
  }
  
  static int da8xx_usb0_clk48_set_parent(struct clk_hw *hw, u8 index)

@@ -494,7 +496,7 @@ static const struct clk_ops da8xx_usb0_clk48_ops = {
.disable= da8xx_usb0_clk48_disable,
.is_enabled = da8xx_usb0_clk48_is_enabled,
.recalc_rate= da8xx_usb0_clk48_recalc_rate,
-   .round_rate = da8xx_usb0_clk48_round_rate,
+   .determine_rate = da8xx_usb0_clk48_determine_rate,
.set_parent = da8xx_usb0_clk48_set_parent,
.get_parent = da8xx_usb0_clk48_get_parent,
  };





Re: [PATCH v2 21/65] clk: davinci: da8xx-cfgchip: Add a determine_rate hook

2022-11-04 Thread David Lechner

On 11/4/22 8:17 AM, Maxime Ripard wrote:

The Davinci DA8xxx cfgchip mux clock implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().



The parent is defined in the device tree and is not expected to change
at runtime, so if I am understanding the patch correctly, setting the
CLK_SET_RATE_NO_REPARENT flag seems correct.



The latter case would be equivalent to setting the flag
CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook
to __clk_mux_determine_rate(). Indeed, if no determine_rate
implementation is provided, clk_round_rate() (through
clk_core_round_rate_nolock()) will call itself on the parent if
CLK_SET_RATE_PARENT is set, and will not change the clock rate
otherwise. __clk_mux_determine_rate() has the exact same behavior when
CLK_SET_RATE_NO_REPARENT is set.

And if it was an oversight, then we are at least explicit about our
behavior now and it can be further refined down the line.

Signed-off-by: Maxime Ripard 
---
  drivers/clk/davinci/da8xx-cfgchip.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/davinci/da8xx-cfgchip.c 
b/drivers/clk/davinci/da8xx-cfgchip.c
index 4103d605e804..c04276bc4051 100644
--- a/drivers/clk/davinci/da8xx-cfgchip.c
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -229,6 +229,7 @@ static u8 da8xx_cfgchip_mux_clk_get_parent(struct clk_hw 
*hw)
  }
  
  static const struct clk_ops da8xx_cfgchip_mux_clk_ops = {

+   .determine_rate = __clk_mux_determine_rate,
.set_parent = da8xx_cfgchip_mux_clk_set_parent,
.get_parent = da8xx_cfgchip_mux_clk_get_parent,
  };
@@ -251,7 +252,7 @@ da8xx_cfgchip_mux_clk_register(struct device *dev,
init.ops = &da8xx_cfgchip_mux_clk_ops;
init.parent_names = parent_names;
init.num_parents = 2;
-   init.flags = 0;
+   init.flags = CLK_SET_RATE_NO_REPARENT;
  
  	mux->hw.init = &init;

mux->regmap = regmap;





Re: [RFC][PATCH v3 00/33] timers: Use timer_shutdown*() before freeing timers

2022-11-04 Thread Linus Torvalds
On Thu, Nov 3, 2022 at 10:48 PM Steven Rostedt  wrote:
>
> Ideally, I would have the first patch go into this rc cycle, which is mostly
> non functional as it will allow the other patches to come in via the 
> respective
> subsystems in the next merge window.

Ack.

I also wonder if we could do the completely trivially correct
conversions immediately.

I'm talking about the scripted ones where it's currently a
"del_timer_sync()", and the very next action is freeing whatever data
structure the timer is in (possibly with something like free_irq() in
between - my point is that there's an unconditional free that is very
clear and unambiguous), so that there is absolutely no question about
whether they should use "timer_shutdown_sync()" or not.

IOW, things like patches 03, 17 and 31, and at least parts others in
this series.

This series clearly has several much more complex cases that need
actual real code review, and I think it would help to have the
completely unambiguous cases out of the way, just to get rid of noise.

So I'd take that first patch, and a scripted set of "this cannot
change any semantics" patches early.

Linus


Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-11-04 Thread Hans de Goede
Hi Matthew, Rafael,

On 10/27/22 14:09, Rafael J. Wysocki wrote:
> On Thu, Oct 27, 2022 at 12:37 PM Hans de Goede  wrote:
>>
>> Hi,
>>
>> On 10/27/22 11:52, Matthew Garrett wrote:
>>> On Thu, Oct 27, 2022 at 11:39:38AM +0200, Hans de Goede wrote:
>>>
 The *only* behavior which actually is new in 6.1 is the native GPU
 drivers now doing the equivalent of:

  if (acpi_video_get_backlight_type() != acpi_backlight_native)
  return;

 In their backlight register paths (i), which is causing the native
 backlight to disappear on your custom laptop setup and on Chromebooks
 (with the Chromebooks case being already solved I hope.).
>>>
>>> It's causing the backlight control to vanish on any machine that isn't
>>> ((acpi_video || vendor interface) || !acpi). Most machines that fall
>>> into that are either weird or Chromebooks or old, but there are machines
>>> that fall into that.
>>
>> I acknowledge that their are machines that fall into this category,
>> but I expect / hope there to be so few of them that we can just DMI
>> quirk our way out if this.
>>
>> I believe the old group to be small because:
>>
>> 1. Generally speaking the "native" control method is usually not
>> present on the really old (pre ACPI video spec) mobile GPUs.
>>
>> 2. On most old laptops I would still expect there to be a vendor
>> interface too, and if both get registered standard desktop environments
>> will prefer the vendor one, so then we need a native DMI quirk to
>> disable the vendor interface anyways and we already have a bunch of
>> those, so some laptops in this group are already covered by DMI quirks.
>>
>> And a fix for the Chromebook case is already in Linus' tree, which
>> just leaves the weird case, of which there will hopefully be only
>> a few.
>>
>> I do share your worry that this might break some machines, but
>> the only way to really find out is to get this code out there
>> I'm afraid.
>>
>> I have just written a blog post asking for people to check if
>> their laptop might be affected; and to report various details
>> to me of their laptop is affected:
>>
>> https://hansdegoede.dreamwidth.org/26548.html
>>
>> Lets wait and see how this goes. If I get (too) many reports then
>> I will send a revert of the addition of the:
>>
>> if (acpi_video_get_backlight_type() != acpi_backlight_native)
>> return;
>>
>> check to the i915 / radeon / amd / nouveau drivers.
>>
>> (And if I only get a couple of reports I will probably just submit
>> DMI quirks for the affected models).
> 
> Sounds reasonable to me, FWIW.

I have received quite a few test reports as a result of my blogpost
(and of the blogpost's mention in an arstechnica article).

Long story short, Matthew, you are right. Quite a few laptop models
will end up with an empty /sys/class/backlight because of the native
backlight class devices no longer registering when
acpi_video_backlight_use_native() returns false.

I will submit a patch-set later today to fix this (by making 
cpi_video_backlight_use_native() always return true for now).

More detailed summary/analysis of the received test reports:

-30 unaffected models

-The following laptop models:
 Acer Aspire 1640
 Apple MacBook 2.1
 Apple MacBook 4.1
 Apple MacBook Pro 7.1 (uses nv_backligh instead of intel_backlight!)
 HP Compaq nc6120
 IBM ThinkPad X40
 System76 Starling Star1

 All only have a native intel_backlight interface and the heuristics from
 acpi_video_get_backlight_type() return acpi_backlight_vendor there causing
 the changes in 6.1 to not register native backlights when
 acpi_video_backlight_use_native() returns false resulting in an empty
 /sys/class/backlight, breaking users ability to control their laptop
 panel's brightness.

 I will submit a patch to always make acpi_video_backlight_use_native()
 return true for now to work around this for 6.1.

 I do plan to try to re-introduce that change again later. First I need to
 change the heuristics to still native on more models so that on models
 where the native backlight is the only (working) entry they will
 return native.

-The Dell N1410 has acpi_video support and acpi_osi_is_win8() returns false
 so acpi_video_get_backlight_type() returns acpi_video, but acpi_video
 fails to register a backlight device due to a_BCM eval error.
 The intel_backlight interface works fine, but this model is going to need
 a DMI-use-native-quirk to avoid intel_backlight disappearing when
 acpi_video_backlight_use_native() is changed back.

-The following laptop models actually use a vendor backlight control method,
 while also having a native backlight entry under /sys/class/backlight:

 Asus EeePC 901   -> native backlight confirmed to also work
 Dell Latitude D610   -> native backlight confirmed to work better then vendor
 Sony Vaio PCG-FRV3   -> native backlight not tested

 Note these will keep working the same as before in 6.1, independent of
 the revert. I've tracked these seperatel

Re: [PATCH v4] dma-buf: fix racing conflict of dma_heap_add()

2022-11-04 Thread Andrew Davis

On 11/4/22 11:05 AM, Dawei Li wrote:

Racing conflict could be:
task A task B
list_for_each_entry
strcmp(h->name))
list_for_each_entry
strcmp(h->name)
kzallockzalloc
.. .
device_create  device_create
list_add
list_add

The root cause is that task B has no idea about the fact someone
else(A) has inserted heap with same name when it calls list_add,
so a potential collision occurs.

Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework")
Signed-off-by: Dawei Li 


LGTM, Thanks,

Acked-by: Andrew Davis 


---
v1: 
https://lore.kernel.org/all/tycp286mb2323950197f60fc3473123b7ca...@tycp286mb2323.jpnp286.prod.outlook.com/
v1->v2: Narrow down locking scope, check the existence of heap before
insertion, as suggested by Andrew Davis.
v2->v3: Remove double checking.
v3->v4: Minor coding style and patch formatting adjustment.
---
  drivers/dma-buf/dma-heap.c | 28 +++-
  1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 8f5848aa144f..59d158873f4c 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
return ERR_PTR(-EINVAL);
}
  
-	/* check the name is unique */

-   mutex_lock(&heap_list_lock);
-   list_for_each_entry(h, &heap_list, list) {
-   if (!strcmp(h->name, exp_info->name)) {
-   mutex_unlock(&heap_list_lock);
-   pr_err("dma_heap: Already registered heap named %s\n",
-  exp_info->name);
-   return ERR_PTR(-EINVAL);
-   }
-   }
-   mutex_unlock(&heap_list_lock);
-
heap = kzalloc(sizeof(*heap), GFP_KERNEL);
if (!heap)
return ERR_PTR(-ENOMEM);
@@ -283,13 +271,27 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
err_ret = ERR_CAST(dev_ret);
goto err2;
}
-   /* Add heap to the list */
+
mutex_lock(&heap_list_lock);
+   /* check the name is unique */
+   list_for_each_entry(h, &heap_list, list) {
+   if (!strcmp(h->name, exp_info->name)) {
+   mutex_unlock(&heap_list_lock);
+   pr_err("dma_heap: Already registered heap named %s\n",
+  exp_info->name);
+   err_ret = ERR_PTR(-EINVAL);
+   goto err3;
+   }
+   }
+
+   /* Add heap to the list */
list_add(&heap->list, &heap_list);
mutex_unlock(&heap_list_lock);
  
  	return heap;
  
+err3:

+   device_destroy(dma_heap_class, heap->heap_devt);
  err2:
cdev_del(&heap->heap_cdev);
  err1:


[PATCH v4] dma-buf: fix racing conflict of dma_heap_add()

2022-11-04 Thread Dawei Li
Racing conflict could be:
task A task B
list_for_each_entry
strcmp(h->name))
   list_for_each_entry
   strcmp(h->name)
kzallockzalloc
.. .
device_create  device_create
list_add
   list_add

The root cause is that task B has no idea about the fact someone
else(A) has inserted heap with same name when it calls list_add,
so a potential collision occurs.

Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework")
Signed-off-by: Dawei Li 
---
v1: 
https://lore.kernel.org/all/tycp286mb2323950197f60fc3473123b7ca...@tycp286mb2323.jpnp286.prod.outlook.com/
v1->v2: Narrow down locking scope, check the existence of heap before
insertion, as suggested by Andrew Davis.
v2->v3: Remove double checking.
v3->v4: Minor coding style and patch formatting adjustment.
---
 drivers/dma-buf/dma-heap.c | 28 +++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 8f5848aa144f..59d158873f4c 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
return ERR_PTR(-EINVAL);
}
 
-   /* check the name is unique */
-   mutex_lock(&heap_list_lock);
-   list_for_each_entry(h, &heap_list, list) {
-   if (!strcmp(h->name, exp_info->name)) {
-   mutex_unlock(&heap_list_lock);
-   pr_err("dma_heap: Already registered heap named %s\n",
-  exp_info->name);
-   return ERR_PTR(-EINVAL);
-   }
-   }
-   mutex_unlock(&heap_list_lock);
-
heap = kzalloc(sizeof(*heap), GFP_KERNEL);
if (!heap)
return ERR_PTR(-ENOMEM);
@@ -283,13 +271,27 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
err_ret = ERR_CAST(dev_ret);
goto err2;
}
-   /* Add heap to the list */
+
mutex_lock(&heap_list_lock);
+   /* check the name is unique */
+   list_for_each_entry(h, &heap_list, list) {
+   if (!strcmp(h->name, exp_info->name)) {
+   mutex_unlock(&heap_list_lock);
+   pr_err("dma_heap: Already registered heap named %s\n",
+  exp_info->name);
+   err_ret = ERR_PTR(-EINVAL);
+   goto err3;
+   }
+   }
+
+   /* Add heap to the list */
list_add(&heap->list, &heap_list);
mutex_unlock(&heap_list_lock);
 
return heap;
 
+err3:
+   device_destroy(dma_heap_class, heap->heap_devt);
 err2:
cdev_del(&heap->heap_cdev);
 err1:
-- 
2.25.1



Re: [PATCH v3 1/8] memory: tegra: Add API for retrieving carveout bounds

2022-11-04 Thread Jon Hunter



On 04/11/2022 15:48, Krzysztof Kozlowski wrote:

On 04/11/2022 11:46, Jon Hunter wrote:


On 04/11/2022 15:35, Krzysztof Kozlowski wrote:

On 04/11/2022 11:33, Jon Hunter wrote:

Hi Thierry, Krzysztof,

On 24/10/2022 14:15, Thierry Reding wrote:

On Tue, Sep 20, 2022 at 11:11:56AM +0300, Mikko Perttunen wrote:

From: Mikko Perttunen 

On Tegra234 NVDEC firmware is loaded from a secure carveout, where it
has been loaded by a bootloader. When booting NVDEC, we need to tell it
the address of this firmware, which we can determine by checking the
starting address of the carveout. As such, add an MC API to query the
bounds of carveouts, and add related information on Tegra234.

Signed-off-by: Mikko Perttunen 
---
v2:
- Add check for 64-bit phys_addr_t. In practice phys_addr_t
 is always 64 bits where this runs, but it avoids warnings in
 compile test.
---
drivers/memory/tegra/mc.c   | 25 +
drivers/memory/tegra/tegra234.c |  5 +
include/soc/tegra/mc.h  | 11 +++
3 files changed, 41 insertions(+)


Krzysztof,

I've applied this to the same tree as the patch that uses it for now.
Let me know if you want me to put this on a separate stable branch for
you to pull in.


Any update on this?


What kind of update do you expect?


Ha! I guess I should be more explicit :-)

Well, I would like to see this change in -next and so I was hoping that
you would respond to the above to indicate how you would like to pull
this in.


The change will be in next via Thierry. I do not have to pull this in.

The maintainer which applies patches is responsible for:
1. Having his tree in linux-next,
2. Sending the patches to upstream maintainer (e.g. arm-soc, Linus)
later in pull request.

There is no job for me here, if I agree with Thierry. There would be a
job if I needed a separate stable branch, but that I did not decide
yet... Do you think I need to pull it? If so, why?



No. Like I said I just want to get this into -next for testing. I had 
_wrongly_ assumed that Thierry was waiting on feedback from you. I see 
this is not the case and so let me check with Thierry where this is.


Jon

--
nvpublic


Re: [PATCH v2 43/65] ASoC: tlv320aic32x4: Add a determine_rate hook

2022-11-04 Thread Mark Brown
On Fri, Nov 04, 2022 at 04:51:23PM +0100, Maxime Ripard wrote:

> Just filling determine_rate if it's missing with
> __clk_mux_determine_rate will possibly pick different parents, and I'm
> fairly certain that this have never been tested on most platforms, and
> will be completely broken. And I don't really want to play a game of
> whack-a-mole adding that flag everywhere it turns out it's broken.

Well, hopefully everyone for whom it's an issue currently will be
objecting to this version of the change anyway so we'll either know
where to set the flag or we'll get the whack-a-mole with the series
being merged?


signature.asc
Description: PGP signature


[RFC] drm/msm: Boost on waits

2022-11-04 Thread Rob Clark
From: Rob Clark 

Minimize interactive latency by boosting frequency when userspace is
waiting on the GPU to finish.

Signed-off-by: Rob Clark 
---
I did contemplate also boosting on dma_fence_wait(), but (a) that would
require some extra plumbing thru gpu-sched, (b) that only captures a
sub-set of wait-on-dma-fence patterns, and (c) waiting on a dma-fence
doesn't always imply urgency (for ex, virglrenderer poll()ing on a dma-
fence to know when to send a fence irq to VM guest).  But the driver
WAIT_FENCE and CPU_PREP ioctls map to things like glFinish() where it
is pretty clear that there is something wishing the GPU would finish
sooner.

 drivers/gpu/drm/msm/msm_drv.c | 7 +--
 drivers/gpu/drm/msm/msm_gem.c | 6 ++
 drivers/gpu/drm/msm/msm_gpu_devfreq.c | 2 +-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index c3b77b44b2aa..017a512982a2 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -894,7 +894,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void 
*data,
 }
 
 static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id,
- ktime_t timeout)
+ ktime_t timeout, struct msm_gpu *gpu)
 {
struct dma_fence *fence;
int ret;
@@ -924,6 +924,9 @@ static int wait_fence(struct msm_gpu_submitqueue *queue, 
uint32_t fence_id,
if (!fence)
return 0;
 
+   if (!dma_fence_is_signaled(fence))
+   msm_devfreq_boost(gpu, 2);
+
ret = dma_fence_wait_timeout(fence, true, timeout_to_jiffies(&timeout));
if (ret == 0) {
ret = -ETIMEDOUT;
@@ -956,7 +959,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, 
void *data,
if (!queue)
return -ENOENT;
 
-   ret = wait_fence(queue, args->fence, to_ktime(args->timeout));
+   ret = wait_fence(queue, args->fence, to_ktime(args->timeout), 
priv->gpu);
 
msm_submitqueue_put(queue);
 
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 1dee0d18abbb..fbda0e3a94f8 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -846,6 +846,12 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t 
op, ktime_t *timeout)
op & MSM_PREP_NOSYNC ? 0 : timeout_to_jiffies(timeout);
long ret;
 
+   if (!dma_resv_test_signaled(obj->resv, dma_resv_usage_rw(write))) {
+   struct msm_drm_private *priv = obj->dev->dev_private;
+
+   msm_devfreq_boost(priv->gpu, 2);
+   }
+
ret = dma_resv_wait_timeout(obj->resv, dma_resv_usage_rw(write),
true,  remain);
if (ret == 0)
diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c 
b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
index 85c443a37e4e..025940eb08d1 100644
--- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c
+++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
@@ -305,7 +305,7 @@ void msm_devfreq_boost(struct msm_gpu *gpu, unsigned factor)
struct msm_gpu_devfreq *df = &gpu->devfreq;
uint64_t freq;
 
-   if (!has_devfreq(gpu))
+   if (!gpu || !has_devfreq(gpu))
return;
 
freq = get_freq(gpu);
-- 
2.38.1



Re: [PATCH v2 43/65] ASoC: tlv320aic32x4: Add a determine_rate hook

2022-11-04 Thread Maxime Ripard
Hi Mark,

On Fri, Nov 04, 2022 at 03:44:53PM +, Mark Brown wrote:
> On Fri, Nov 04, 2022 at 02:18:00PM +0100, Maxime Ripard wrote:
> 
> > So, the set_parent hook is effectively unused, possibly because of an
> > oversight. However, it could also be an explicit decision by the
> > original author to avoid any reparenting but through an explicit call to
> > clk_set_parent().
> 
> > The latter case would be equivalent to setting the flag
> > CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook
> > to __clk_mux_determine_rate(). Indeed, if no determine_rate
> > implementation is provided, clk_round_rate() (through
> > clk_core_round_rate_nolock()) will call itself on the parent if
> > CLK_SET_RATE_PARENT is set, and will not change the clock rate
> > otherwise. __clk_mux_determine_rate() has the exact same behavior when
> > CLK_SET_RATE_NO_REPARENT is set.
> 
> > And if it was an oversight, then we are at least explicit about our
> > behavior now and it can be further refined down the line.
> 
> Given that the current approach involves patching every single user to
> set a default implementation it feels like it might be more
> straightforward to just have the clock API use that implementation if
> none is defined - as you say there's already a flag to indicate the
> unusual case where there's a solid reason to prevent reparenting.  It
> feels like the resulting API is more straightforward.

That would be another solution indeed. The thing is, most places where
determine_rate is missing seems to be oversight, and the flag is missing
as well.

Just filling determine_rate if it's missing with
__clk_mux_determine_rate will possibly pick different parents, and I'm
fairly certain that this have never been tested on most platforms, and
will be completely broken. And I don't really want to play a game of
whack-a-mole adding that flag everywhere it turns out it's broken.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v3 1/8] memory: tegra: Add API for retrieving carveout bounds

2022-11-04 Thread Krzysztof Kozlowski
On 04/11/2022 11:46, Jon Hunter wrote:
> 
> On 04/11/2022 15:35, Krzysztof Kozlowski wrote:
>> On 04/11/2022 11:33, Jon Hunter wrote:
>>> Hi Thierry, Krzysztof,
>>>
>>> On 24/10/2022 14:15, Thierry Reding wrote:
 On Tue, Sep 20, 2022 at 11:11:56AM +0300, Mikko Perttunen wrote:
> From: Mikko Perttunen 
>
> On Tegra234 NVDEC firmware is loaded from a secure carveout, where it
> has been loaded by a bootloader. When booting NVDEC, we need to tell it
> the address of this firmware, which we can determine by checking the
> starting address of the carveout. As such, add an MC API to query the
> bounds of carveouts, and add related information on Tegra234.
>
> Signed-off-by: Mikko Perttunen 
> ---
> v2:
> - Add check for 64-bit phys_addr_t. In practice phys_addr_t
> is always 64 bits where this runs, but it avoids warnings in
> compile test.
> ---
>drivers/memory/tegra/mc.c   | 25 +
>drivers/memory/tegra/tegra234.c |  5 +
>include/soc/tegra/mc.h  | 11 +++
>3 files changed, 41 insertions(+)

 Krzysztof,

 I've applied this to the same tree as the patch that uses it for now.
 Let me know if you want me to put this on a separate stable branch for
 you to pull in.
>>>
>>> Any update on this?
>>
>> What kind of update do you expect?
> 
> Ha! I guess I should be more explicit :-)
> 
> Well, I would like to see this change in -next and so I was hoping that 
> you would respond to the above to indicate how you would like to pull 
> this in.

The change will be in next via Thierry. I do not have to pull this in.

The maintainer which applies patches is responsible for:
1. Having his tree in linux-next,
2. Sending the patches to upstream maintainer (e.g. arm-soc, Linus)
later in pull request.

There is no job for me here, if I agree with Thierry. There would be a
job if I needed a separate stable branch, but that I did not decide
yet... Do you think I need to pull it? If so, why?

Best regards,
Krzysztof



Re: [PATCH v3 1/8] memory: tegra: Add API for retrieving carveout bounds

2022-11-04 Thread Jon Hunter



On 04/11/2022 15:35, Krzysztof Kozlowski wrote:

On 04/11/2022 11:33, Jon Hunter wrote:

Hi Thierry, Krzysztof,

On 24/10/2022 14:15, Thierry Reding wrote:

On Tue, Sep 20, 2022 at 11:11:56AM +0300, Mikko Perttunen wrote:

From: Mikko Perttunen 

On Tegra234 NVDEC firmware is loaded from a secure carveout, where it
has been loaded by a bootloader. When booting NVDEC, we need to tell it
the address of this firmware, which we can determine by checking the
starting address of the carveout. As such, add an MC API to query the
bounds of carveouts, and add related information on Tegra234.

Signed-off-by: Mikko Perttunen 
---
v2:
- Add check for 64-bit phys_addr_t. In practice phys_addr_t
is always 64 bits where this runs, but it avoids warnings in
compile test.
---
   drivers/memory/tegra/mc.c   | 25 +
   drivers/memory/tegra/tegra234.c |  5 +
   include/soc/tegra/mc.h  | 11 +++
   3 files changed, 41 insertions(+)


Krzysztof,

I've applied this to the same tree as the patch that uses it for now.
Let me know if you want me to put this on a separate stable branch for
you to pull in.


Any update on this?


What kind of update do you expect?


Ha! I guess I should be more explicit :-)

Well, I would like to see this change in -next and so I was hoping that 
you would respond to the above to indicate how you would like to pull 
this in.


Cheers!
Jon

--
nvpublic


Re: [PATCH v2 43/65] ASoC: tlv320aic32x4: Add a determine_rate hook

2022-11-04 Thread Mark Brown
On Fri, Nov 04, 2022 at 02:18:00PM +0100, Maxime Ripard wrote:

> So, the set_parent hook is effectively unused, possibly because of an
> oversight. However, it could also be an explicit decision by the
> original author to avoid any reparenting but through an explicit call to
> clk_set_parent().

> The latter case would be equivalent to setting the flag
> CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook
> to __clk_mux_determine_rate(). Indeed, if no determine_rate
> implementation is provided, clk_round_rate() (through
> clk_core_round_rate_nolock()) will call itself on the parent if
> CLK_SET_RATE_PARENT is set, and will not change the clock rate
> otherwise. __clk_mux_determine_rate() has the exact same behavior when
> CLK_SET_RATE_NO_REPARENT is set.

> And if it was an oversight, then we are at least explicit about our
> behavior now and it can be further refined down the line.

Given that the current approach involves patching every single user to
set a default implementation it feels like it might be more
straightforward to just have the clock API use that implementation if
none is defined - as you say there's already a flag to indicate the
unusual case where there's a solid reason to prevent reparenting.  It
feels like the resulting API is more straightforward.


signature.asc
Description: PGP signature


Re: [PATCH v3 1/8] memory: tegra: Add API for retrieving carveout bounds

2022-11-04 Thread Krzysztof Kozlowski
On 04/11/2022 11:33, Jon Hunter wrote:
> Hi Thierry, Krzysztof,
> 
> On 24/10/2022 14:15, Thierry Reding wrote:
>> On Tue, Sep 20, 2022 at 11:11:56AM +0300, Mikko Perttunen wrote:
>>> From: Mikko Perttunen 
>>>
>>> On Tegra234 NVDEC firmware is loaded from a secure carveout, where it
>>> has been loaded by a bootloader. When booting NVDEC, we need to tell it
>>> the address of this firmware, which we can determine by checking the
>>> starting address of the carveout. As such, add an MC API to query the
>>> bounds of carveouts, and add related information on Tegra234.
>>>
>>> Signed-off-by: Mikko Perttunen 
>>> ---
>>> v2:
>>> - Add check for 64-bit phys_addr_t. In practice phys_addr_t
>>>is always 64 bits where this runs, but it avoids warnings in
>>>compile test.
>>> ---
>>>   drivers/memory/tegra/mc.c   | 25 +
>>>   drivers/memory/tegra/tegra234.c |  5 +
>>>   include/soc/tegra/mc.h  | 11 +++
>>>   3 files changed, 41 insertions(+)
>>
>> Krzysztof,
>>
>> I've applied this to the same tree as the patch that uses it for now.
>> Let me know if you want me to put this on a separate stable branch for
>> you to pull in.
> 
> Any update on this?

What kind of update do you expect?

Best regards,
Krzysztof



Re: [PATCH v3 1/8] memory: tegra: Add API for retrieving carveout bounds

2022-11-04 Thread Jon Hunter

Hi Thierry, Krzysztof,

On 24/10/2022 14:15, Thierry Reding wrote:

On Tue, Sep 20, 2022 at 11:11:56AM +0300, Mikko Perttunen wrote:

From: Mikko Perttunen 

On Tegra234 NVDEC firmware is loaded from a secure carveout, where it
has been loaded by a bootloader. When booting NVDEC, we need to tell it
the address of this firmware, which we can determine by checking the
starting address of the carveout. As such, add an MC API to query the
bounds of carveouts, and add related information on Tegra234.

Signed-off-by: Mikko Perttunen 
---
v2:
- Add check for 64-bit phys_addr_t. In practice phys_addr_t
   is always 64 bits where this runs, but it avoids warnings in
   compile test.
---
  drivers/memory/tegra/mc.c   | 25 +
  drivers/memory/tegra/tegra234.c |  5 +
  include/soc/tegra/mc.h  | 11 +++
  3 files changed, 41 insertions(+)


Krzysztof,

I've applied this to the same tree as the patch that uses it for now.
Let me know if you want me to put this on a separate stable branch for
you to pull in.


Any update on this?

Thanks!
Jon

--
nvpublic


Re: [PATCH v1 3/5] arm64: dts: qcom: sm8450-hdk: enable display hardware

2022-11-04 Thread Vinod Koul
On 04-11-22, 16:13, Dmitry Baryshkov wrote:
> Enable MDSS/DPU/DSI0 on SM8450-HDK device. Note, there is no panel
> configuration (yet).
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  arch/arm64/boot/dts/qcom/sm8450-hdk.dts | 18 ++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts 
> b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
> index 38ccd44620d0..e1a4cf1ee51d 100644
> --- a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
> +++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
> @@ -442,3 +442,21 @@ &usb_1_qmpphy {
>   vdda-phy-supply = <&vreg_l6b_1p2>;
>   vdda-pll-supply = <&vreg_l1b_0p91>;
>  };
> +
> +&mdss {
> + status = "okay";
> +};
> +
> +&mdss_mdp {
> + status = "okay";
> +};
> +
> +&dsi0 {
> + status = "okay";
> + vdda-supply = <&vreg_l6b_1p2>;
> +};
> +
> +&dsi0_phy {
> + status = "okay";
> + vdds-supply = <&vreg_l5b_0p88>;
> +};

This is missing dispcc, please enable that node too.

Also, sort this please

> -- 
> 2.35.1

-- 
~Vinod


[PATCH v3 2/2] drm/msm: Hangcheck progress detection

2022-11-04 Thread Rob Clark
From: Rob Clark 

If the hangcheck timer expires, check if the fw's position in the
cmdstream has advanced (changed) since last timer expiration, and
allow it up to three additional "extensions" to it's alotted time.
The intention is to continue to catch "shader stuck in a loop" type
hangs quickly, but allow more time for things that are actually
making forward progress.

Because we need to sample the CP state twice to detect if there has
not been progress, this also cuts the the timer's duration in half.

v2: Fix typo (REG_A6XX_CP_CSQ_IB2_STAT), add comment
v3: Only halve hangcheck timer duration for generations which
support progress detection (hdanton); removed unused a5xx
progress (without knowing how to adjust for data buffered
in ROQ it is too likely to report a false negative)

Signed-off-by: Rob Clark 
Reviewed-by: Akhil P Oommen 
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 34 +++
 drivers/gpu/drm/msm/msm_drv.c |  1 -
 drivers/gpu/drm/msm/msm_drv.h |  8 ++-
 drivers/gpu/drm/msm/msm_gpu.c | 31 +++-
 drivers/gpu/drm/msm/msm_gpu.h |  3 +++
 drivers/gpu/drm/msm/msm_ringbuffer.h  | 24 +++
 6 files changed, 98 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 1ff605c18ee6..7fe60c65a1eb 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1843,6 +1843,39 @@ static uint32_t a6xx_get_rptr(struct msm_gpu *gpu, 
struct msm_ringbuffer *ring)
return ring->memptrs->rptr = gpu_read(gpu, REG_A6XX_CP_RB_RPTR);
 }
 
+static bool a6xx_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+   struct msm_cp_state cp_state = {
+   .ib1_base = gpu_read64(gpu, REG_A6XX_CP_IB1_BASE),
+   .ib2_base = gpu_read64(gpu, REG_A6XX_CP_IB2_BASE),
+   .ib1_rem  = gpu_read(gpu, REG_A6XX_CP_IB1_REM_SIZE),
+   .ib2_rem  = gpu_read(gpu, REG_A6XX_CP_IB2_REM_SIZE),
+   };
+   bool progress;
+
+   /*
+* Adjust the remaining data to account for what has already been
+* fetched from memory, but not yet consumed by the SQE.
+*
+* This is not *technically* correct, the amount buffered could
+* exceed the IB size due to hw prefetching ahead, but:
+*
+* (1) We aren't trying to find the exact position, just whether
+* progress has been made
+* (2) The CP_REG_TO_MEM at the end of a submit should be enough
+* to prevent prefetching into an unrelated submit.  (And
+* either way, at some point the ROQ will be full.)
+*/
+   cp_state.ib1_rem += gpu_read(gpu, REG_A6XX_CP_CSQ_IB1_STAT) >> 16;
+   cp_state.ib2_rem += gpu_read(gpu, REG_A6XX_CP_CSQ_IB2_STAT) >> 16;
+
+   progress = !!memcmp(&cp_state, &ring->last_cp_state, sizeof(cp_state));
+
+   ring->last_cp_state = cp_state;
+
+   return progress;
+}
+
 static u32 a618_get_speed_bin(u32 fuse)
 {
if (fuse == 0)
@@ -1961,6 +1994,7 @@ static const struct adreno_gpu_funcs funcs = {
.create_address_space = a6xx_create_address_space,
.create_private_address_space = 
a6xx_create_private_address_space,
.get_rptr = a6xx_get_rptr,
+   .progress = a6xx_progress,
},
.get_timestamp = a6xx_get_timestamp,
 };
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 670651cdfa79..c3b77b44b2aa 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -419,7 +419,6 @@ static int msm_drm_init(struct device *dev, const struct 
drm_driver *drv)
priv->dev = ddev;
 
priv->wq = alloc_ordered_workqueue("msm", 0);
-   priv->hangcheck_period = DRM_MSM_HANGCHECK_DEFAULT_PERIOD;
 
INIT_LIST_HEAD(&priv->objects);
mutex_init(&priv->obj_lock);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 0609daf4fa4c..876d8d5eec2f 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -225,7 +225,13 @@ struct msm_drm_private {
 
struct drm_atomic_state *pm_state;
 
-   /* For hang detection, in ms */
+   /**
+* hangcheck_period: For hang detection, in ms
+*
+* Note that in practice, a submit/job will get at least two hangcheck
+* periods, due to checking for progress being implemented as simply
+* "have the CP position registers changed since last time?"
+*/
unsigned int hangcheck_period;
 
/**
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 3dffee54a951..bfef659d3a5c 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -500,6 +500,21 @@ static void hangcheck_timer_reset(struct msm_gpu *gpu)
round_jiffies_up(jiffies + 
msecs_to

[PATCH v3 1/2] drm/msm/adreno: Simplify read64/write64 helpers

2022-11-04 Thread Rob Clark
From: Rob Clark 

The _HI reg is always following the _LO reg, so no need to pass these
offsets seprately.

Signed-off-by: Rob Clark 
Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Akhil P Oommen 
---
 drivers/gpu/drm/msm/adreno/a4xx_gpu.c   |  3 +--
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c   | 27 -
 drivers/gpu/drm/msm/adreno/a5xx_preempt.c   |  4 +--
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 24 ++
 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c |  3 +--
 drivers/gpu/drm/msm/msm_gpu.h   | 12 -
 6 files changed, 27 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 7cb8d9849c07..a10feb8a4194 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -606,8 +606,7 @@ static int a4xx_pm_suspend(struct msm_gpu *gpu) {
 
 static int a4xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
 {
-   *value = gpu_read64(gpu, REG_A4XX_RBBM_PERFCTR_CP_0_LO,
-   REG_A4XX_RBBM_PERFCTR_CP_0_HI);
+   *value = gpu_read64(gpu, REG_A4XX_RBBM_PERFCTR_CP_0_LO);
 
return 0;
 }
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 3dcec7acb384..ba22d3c918bc 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -605,11 +605,9 @@ static int a5xx_ucode_init(struct msm_gpu *gpu)
a5xx_ucode_check_version(a5xx_gpu, a5xx_gpu->pfp_bo);
}
 
-   gpu_write64(gpu, REG_A5XX_CP_ME_INSTR_BASE_LO,
-   REG_A5XX_CP_ME_INSTR_BASE_HI, a5xx_gpu->pm4_iova);
+   gpu_write64(gpu, REG_A5XX_CP_ME_INSTR_BASE_LO, a5xx_gpu->pm4_iova);
 
-   gpu_write64(gpu, REG_A5XX_CP_PFP_INSTR_BASE_LO,
-   REG_A5XX_CP_PFP_INSTR_BASE_HI, a5xx_gpu->pfp_iova);
+   gpu_write64(gpu, REG_A5XX_CP_PFP_INSTR_BASE_LO, a5xx_gpu->pfp_iova);
 
return 0;
 }
@@ -868,8 +866,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
 * memory rendering at this point in time and we don't want to block off
 * part of the virtual memory space.
 */
-   gpu_write64(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO,
-   REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, 0x);
+   gpu_write64(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO, 0x);
gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x);
 
/* Put the GPU into 64 bit by default */
@@ -908,8 +905,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
return ret;
 
/* Set the ringbuffer address */
-   gpu_write64(gpu, REG_A5XX_CP_RB_BASE, REG_A5XX_CP_RB_BASE_HI,
-   gpu->rb[0]->iova);
+   gpu_write64(gpu, REG_A5XX_CP_RB_BASE, gpu->rb[0]->iova);
 
/*
 * If the microcode supports the WHERE_AM_I opcode then we can use that
@@ -936,7 +932,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
}
 
gpu_write64(gpu, REG_A5XX_CP_RB_RPTR_ADDR,
-   REG_A5XX_CP_RB_RPTR_ADDR_HI, shadowptr(a5xx_gpu, 
gpu->rb[0]));
+   shadowptr(a5xx_gpu, gpu->rb[0]));
} else if (gpu->nr_rings > 1) {
/* Disable preemption if WHERE_AM_I isn't available */
a5xx_preempt_fini(gpu);
@@ -1239,9 +1235,9 @@ static void a5xx_fault_detect_irq(struct msm_gpu *gpu)
gpu_read(gpu, REG_A5XX_RBBM_STATUS),
gpu_read(gpu, REG_A5XX_CP_RB_RPTR),
gpu_read(gpu, REG_A5XX_CP_RB_WPTR),
-   gpu_read64(gpu, REG_A5XX_CP_IB1_BASE, REG_A5XX_CP_IB1_BASE_HI),
+   gpu_read64(gpu, REG_A5XX_CP_IB1_BASE),
gpu_read(gpu, REG_A5XX_CP_IB1_BUFSZ),
-   gpu_read64(gpu, REG_A5XX_CP_IB2_BASE, REG_A5XX_CP_IB2_BASE_HI),
+   gpu_read64(gpu, REG_A5XX_CP_IB2_BASE),
gpu_read(gpu, REG_A5XX_CP_IB2_BUFSZ));
 
/* Turn off the hangcheck timer to keep it from bothering us */
@@ -1427,8 +1423,7 @@ static int a5xx_pm_suspend(struct msm_gpu *gpu)
 
 static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
 {
-   *value = gpu_read64(gpu, REG_A5XX_RBBM_ALWAYSON_COUNTER_LO,
-   REG_A5XX_RBBM_ALWAYSON_COUNTER_HI);
+   *value = gpu_read64(gpu, REG_A5XX_RBBM_ALWAYSON_COUNTER_LO);
 
return 0;
 }
@@ -1465,8 +1460,7 @@ static int a5xx_crashdumper_run(struct msm_gpu *gpu,
if (IS_ERR_OR_NULL(dumper->ptr))
return -EINVAL;
 
-   gpu_write64(gpu, REG_A5XX_CP_CRASH_SCRIPT_BASE_LO,
-   REG_A5XX_CP_CRASH_SCRIPT_BASE_HI, dumper->iova);
+   gpu_write64(gpu, REG_A5XX_CP_CRASH_SCRIPT_BASE_LO, dumper->iova);
 
gpu_write(gpu, REG_A5XX_CP_CRASH_DUMP_CNTL, 1);
 
@@ -1666,8 +1660,7 @@ static u64 a5xx_gpu_busy(struct msm_gpu *gpu, unsigned 
long *out_sample_rate)
 {
u64 busy_cycles;
 
-   busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_P

[PATCH v3 0/2] drm/msm: Improved hang detection

2022-11-04 Thread Rob Clark
From: Rob Clark 

Try to detect when submit jobs are making forward progress and give them
a bit more time.

Rob Clark (2):
  drm/msm/adreno: Simplify read64/write64 helpers
  drm/msm: Hangcheck progress detection

 drivers/gpu/drm/msm/adreno/a4xx_gpu.c   |  3 +-
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c   | 27 --
 drivers/gpu/drm/msm/adreno/a5xx_preempt.c   |  4 +-
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 58 +++--
 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c |  3 +-
 drivers/gpu/drm/msm/msm_drv.c   |  1 -
 drivers/gpu/drm/msm/msm_drv.h   |  8 ++-
 drivers/gpu/drm/msm/msm_gpu.c   | 31 ++-
 drivers/gpu/drm/msm/msm_gpu.h   | 15 +++---
 drivers/gpu/drm/msm/msm_ringbuffer.h| 24 +
 10 files changed, 125 insertions(+), 49 deletions(-)

-- 
2.38.1



Re: Try to address the DMA-buf coherency problem

2022-11-04 Thread Christian König

Am 04.11.22 um 15:58 schrieb Rob Clark:

On Wed, Nov 2, 2022 at 5:21 AM Christian König
 wrote:

Hi Lucas,

Am 02.11.22 um 12:39 schrieb Lucas Stach:

Hi Christian,

going to reply in more detail when I have some more time, so just some
quick thoughts for now.

Am Mittwoch, dem 02.11.2022 um 12:18 +0100 schrieb Christian König:

Am 01.11.22 um 22:09 schrieb Nicolas Dufresne:

[SNIP]

As far as I can see it you guys just allocate a buffer from a V4L2
device, fill it with data and send it to Wayland for displaying.

To be honest I'm really surprised that the Wayland guys hasn't pushed
back on this practice already.

This only works because the Wayland as well as X display pipeline is
smart enough to insert an extra copy when it find that an imported
buffer can't be used as a framebuffer directly.


With bracketed access you could even make this case work, as the dGPU
would be able to slurp a copy of the dma-buf into LMEM for scanout.

Well, this copy is what we are trying to avoid here. The codec should
pump the data into LMEM in the first place.


For the dGPU VRAM case, shouldn't this be amdgpu re-importing it's own
dmabuf, which more or less bypasses dma-buf to get back the backing
GEM obj?


When the codec and scanout is on the same device, then yes.

But we already had cases where the codec was on the dGPU and scanout 
happened on the integrated engine.


Regards,
Christian.



BR,
-R




Re: [PATCH v2 56/65] clk: ingenic: cgu: Switch to determine_rate

2022-11-04 Thread Maxime Ripard
Hi Paul,

On Fri, Nov 04, 2022 at 02:31:20PM +, Paul Cercueil wrote:
> Le ven. 4 nov. 2022 à 14:18:13 +0100, Maxime Ripard  a
> écrit :
> > The Ingenic CGU clocks implements a mux with a set_parent hook, but
> > doesn't provide a determine_rate implementation.
> > 
> > This is a bit odd, since set_parent() is there to, as its name implies,
> > change the parent of a clock. However, the most likely candidate to
> > trigger that parent change is a call to clk_set_rate(), with
> > determine_rate() figuring out which parent is the best suited for a
> > given rate.
> > 
> > The other trigger would be a call to clk_set_parent(), but it's far less
> > used, and it doesn't look like there's any obvious user for that clock.
> > 
> > So, the set_parent hook is effectively unused, possibly because of an
> > oversight. However, it could also be an explicit decision by the
> > original author to avoid any reparenting but through an explicit call to
> > clk_set_parent().
> > 
> > The driver does implement round_rate() though, which means that we can
> > change the rate of the clock, but we will never get to change the
> > parent.
> > 
> > However, It's hard to tell whether it's been done on purpose or not.
> > 
> > Since we'll start mandating a determine_rate() implementation, let's
> > convert the round_rate() implementation to a determine_rate(), which
> > will also make the current behavior explicit. And if it was an
> > oversight, the clock behaviour can be adjusted later on.
> 
> So it's partly on purpose, partly because I didn't know about
> .determine_rate.
> 
> There's nothing odd about having a lonely .set_parent callback; in my case
> the clocks are parented from the device tree.
> 
> Having the clocks driver trigger a parent change when requesting a rate
> change sounds very dangerous, IMHO. My MMC controller can be parented to the
> external 48 MHz oscillator, and if the card requests 50 MHz, it could switch
> to one of the PLLs. That works as long as the PLLs don't change rate, but if
> one is configured as driving the CPU clock, it becomes messy.
> The thing is, the clocks driver has no way to know whether or not it is
> "safe" to use a designated parent.
> 
> For that reason, in practice, I never actually want to have a clock
> re-parented - it's almost always a bad idea vs. sticking to the parent clock
> configured in the DTS.

Yeah, and this is totally fine. But we need to be explicit about it. The
determine_rate implementation I did in all the patches is an exact
equivalent to the round_rate one if there was one. We will never ask to
change the parent.

Given what you just said, I would suggest to set the
CLK_SET_RATE_NO_REPARENT flag as well.

> 
> > Signed-off-by: Maxime Ripard 
> > ---
> >  drivers/clk/ingenic/cgu.c | 15 ---
> >  1 file changed, 8 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
> > index 1f7ba30f5a1b..0c9c8344ad11 100644
> > --- a/drivers/clk/ingenic/cgu.c
> > +++ b/drivers/clk/ingenic/cgu.c
> > @@ -491,22 +491,23 @@ ingenic_clk_calc_div(struct clk_hw *hw,
> > return div;
> >  }
> > 
> > -static long
> > -ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
> > -  unsigned long *parent_rate)
> > +static int ingenic_clk_determine_rate(struct clk_hw *hw,
> > + struct clk_rate_request *req)
> >  {
> > struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
> > const struct ingenic_cgu_clk_info *clk_info =
> > to_clk_info(ingenic_clk);
> > unsigned int div = 1;
> > 
> > if (clk_info->type & CGU_CLK_DIV)
> > -   div = ingenic_clk_calc_div(hw, clk_info, *parent_rate, 
> > req_rate);
> > +   div = ingenic_clk_calc_div(hw, clk_info, req->best_parent_rate,
> > +  req->rate);
> 
> Sorry but I'm not sure that this works.
> 
> You replace the "parent_rate" with the "best_parent_rate", and that means
> you only check the requested rate vs. the parent with the highest frequency,
> and not vs. the actual parent that will be used.

best_parent_rate is initialized to the current parent rate, not the
parent with the highest frequency:
https://elixir.bootlin.com/linux/v6.1-rc3/source/drivers/clk/clk.c#L1471

Maxime


signature.asc
Description: PGP signature


Re: Try to address the DMA-buf coherency problem

2022-11-04 Thread Rob Clark
On Wed, Nov 2, 2022 at 5:21 AM Christian König
 wrote:
>
> Hi Lucas,
>
> Am 02.11.22 um 12:39 schrieb Lucas Stach:
> > Hi Christian,
> >
> > going to reply in more detail when I have some more time, so just some
> > quick thoughts for now.
> >
> > Am Mittwoch, dem 02.11.2022 um 12:18 +0100 schrieb Christian König:
> >> Am 01.11.22 um 22:09 schrieb Nicolas Dufresne:
> >>> [SNIP]
> >> As far as I can see it you guys just allocate a buffer from a V4L2
> >> device, fill it with data and send it to Wayland for displaying.
> >>
> >> To be honest I'm really surprised that the Wayland guys hasn't pushed
> >> back on this practice already.
> >>
> >> This only works because the Wayland as well as X display pipeline is
> >> smart enough to insert an extra copy when it find that an imported
> >> buffer can't be used as a framebuffer directly.
> >>
> > With bracketed access you could even make this case work, as the dGPU
> > would be able to slurp a copy of the dma-buf into LMEM for scanout.
>
> Well, this copy is what we are trying to avoid here. The codec should
> pump the data into LMEM in the first place.
>

For the dGPU VRAM case, shouldn't this be amdgpu re-importing it's own
dmabuf, which more or less bypasses dma-buf to get back the backing
GEM obj?

BR,
-R


Re: [PATCH v27 6/7] drm/mediatek: add drm ovl_adaptor sub driver for MT8195

2022-11-04 Thread Nícolas F . R . A . Prado
On Fri, Nov 04, 2022 at 10:57:28AM +, Nancy Lin (林欣螢) wrote:
> Dear Nicolas,
> 
> Thanks for the review.
> 
> On Thu, 2022-11-03 at 17:28 -0400, Nícolas F. R. A. Prado wrote:
> > On Thu, Nov 03, 2022 at 11:26:09AM +0800, Nancy.Lin wrote:
> > > Add drm ovl_adaptor sub driver. Bring up ovl_adaptor sub driver if
> > > the component exists in the path.
> > > 
> > > Signed-off-by: Nancy.Lin 
> > > Reviewed-by: AngeloGioacchino Del Regno <
> > > angelogioacchino.delre...@collabora.com>
> > > Reviewed-by: CK Hu 
> > > Tested-by: AngeloGioacchino Del Regno <
> > > angelogioacchino.delre...@collabora.com>
> > > Tested-by: Bo-Chen Chen 
> > > Tested-by: Nícolas F. R. A. Prado 
> > > Change-Id: I0501f3c80e78ec8279366cba9c137a2edd7a852e
> > > ---
> > >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  61 -
> > >  drivers/gpu/drm/mediatek/mtk_drm_crtc.h |   2 +-
> > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 129 --
> > > --
> > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  50 +++-
> > >  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  78 ++--
> > >  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  12 +-
> > >  6 files changed, 209 insertions(+), 123 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > index 30dcb65d8a5a..ce5617ad04cb 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > 
> > [..]
> > >  int mtk_drm_crtc_create(struct drm_device *drm_dev,
> > > - const enum mtk_ddp_comp_id *path, unsigned int
> > > path_len,
> > > + const unsigned int *path, unsigned int
> > > path_len,
> > 
> > Hi Nancy,
> > 
> > why is 'enum mtk_ddp_comp_id' being changed to 'unsigned int'
> > throughout this
> > patch? Was this intentional?
> > 
> > I saw that this change happened between v16 [1] and v17 [2], but I
> > didn't see
> > any reply or mention about this in the commit message or cover
> > letter.
> > 
> > Thanks,
> > Nícolas
> > 
> > [1] 
> > https://lore.kernel.org/all/20220318142009.2796-21-nancy@mediatek.com/
> > [2] 
> > https://lore.kernel.org/all/20220416020749.29010-20-nancy@mediatek.com/
> 
> 
> The change is for the review in [1] to expose each mod instead of ovl
> adaptor to mtk_mutex.
> Ovl adaptor is an application that combine these mod to achieve ovl
> function, and it's not a real component in mtk_mmsys/mtk_mutex.
> 
> For the above comment, I discussed the solution with MediaTek DRM
> reviewer CK.Hu internally.
> 1. remove the DDP_COMPONENT_OVL_ADAPTOR in enum mtk_ddp_comp_id{}  (ref
> [2])
> 2. add DRM driver component define "DDP_COMPONENT_DRM_OVL_ADAPTOR" in
> mtk_drm_drv.h (ref[3])
> 3. replace mmsys compoent DDP_COMPONENT_OVL_ADAPTOR with DRM driver
> compoent DDP_COMPONENT_DRM_OVL_ADAPTOR in drm mt8195_mtk_ddp_ext[] path
> array. (ref[3] - mtk_drm_drv.c)
>
> static const unsigned int mt8195_mtk_ddp_ext[] = {
>   DDP_COMPONENT_DRM_OVL_ADAPTOR,
>   DDP_COMPONENT_MERGE5,
>   DDP_COMPONENT_DP_INTF1,
> };
> Because the DDP_COMPONENT_DRM_OVL_ADAPTOR is not a real mmsys
> component, change to use "unsigned int" instead of "enum
> mtk_ddp_comp_id{}"

Ah okay, that makes sense. Thank you for the clarification.

Thanks,
Nícolas

> 
> 
> [1] 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20220318142009.2796-10-nancy@mediatek.com/
> [2] 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20220318142009.2796-5-nancy@mediatek.com/
> [3] 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20221103032610.9217-7-nancy@mediatek.com/
> 
> Thanks,
> Nancy
> 


Re: Try to address the DMA-buf coherency problem

2022-11-04 Thread Christian König

Am 04.11.22 um 14:38 schrieb Nicolas Dufresne:

Le vendredi 04 novembre 2022 à 10:03 +0100, Christian König a écrit :

Am 03.11.22 um 23:16 schrieb Nicolas Dufresne:

[SNIP]

Was there APIs suggested to actually make it manageable by userland to allocate
from the GPU? Yes, this what Linux Device Allocator idea is for. Is that API
ready, no.

Well, that stuff is absolutely ready:
https://elixir.bootlin.com/linux/latest/source/drivers/dma-buf/heaps/system_heap.c#L175
What do you think I'm talking about all the time?

I'm aware of DMA Heap, still have few gaps, but this unrelated to coherency (we
can discuss offline, with Daniel S.). For DMABuf Heap, its used in many forks by
vendors in production. There is an upstream proposal for GStreamer, but review
comments were never addressed, in short, its stalled, and it waiting for a
volunteer. It might also be based on very old implementation of DMABuf Heap,
needs to be verified in depth for sure as the time have passed.

https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1391


Well this is actually quite related to coherency.

As general purpose framework it's mandatory for DMA Heaps to support the 
coherency callbacks. And as far as I can see they are indeed correctly 
implemented.


So if you allocate from a DMA Heap it should be guaranteed that sharing 
with all devices work correctly, no matter if they write with the CPU or 
don't snoop the CPU cache. That's essentially what those heaps are good for.


I just don't know how you should select between the contiguous and the 
system heap since I'm not deep enough in the userspace side of this.


We should have come up with heaps earlier and don't implement so many 
different system memory allocators in the drivers in the first place.



DMA-buf has a lengthy section about CPU access to buffers and clearly
documents how all of that is supposed to work:
https://elixir.bootlin.com/linux/latest/source/drivers/dma-buf/dma-buf.c#L1160
This includes braketing of CPU access with dma_buf_begin_cpu_access()
and dma_buf_end_cpu_access(), as well as transaction management between
devices and the CPU and even implicit synchronization.

This specification is then implemented by the different drivers
including V4L2:
https://elixir.bootlin.com/linux/latest/source/drivers/media/common/videobuf2/videobuf2-dma-sg.c#L473

As well as the different DRM drivers:
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c#L117
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c#L234

I know, I've implement the userspace bracketing for this in GStreamer [1] before
DMAbuf Heap was merged and was one of the reporter for the missing bracketing in
VB2. Was tested against i915 driver. Note, this is just a fallback, the
performance is terrible, memory exported by (at least my old i915 HW) is not
cacheable on CPU. Though, between corrupted image and bad performance or just
bad performance, we decided that it was better to have the second. When the
DMABuf is backed by CPU cacheable memory, peformance is great and CPU fallback
works. Work is in progress to better handle these two cases generically. For
now, sometimes the app need to get involved, but this is only happens on
embedded/controlled kind of use cases. What matters is that application that
needs this can do it.

[1] 
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/subprojects/gst-plugins-base/gst-libs/gst/allocators/gstdmabuf.c


Yeah, I've heard complains about that before with people asking if we 
couldn't map buffers exporter by the GPU as cacheable and then flush it 
on demand.


For i915 that's more or less possible because it just uses stolen system 
memory, but pretty much any other dGPU uses local memory and mapping a 
PCIe BAR cacheable is really a no-go.



This design was then used by us with various media players on different
customer projects, including QNAP https://www.qnap.com/en/product/ts-877
as well as the newest Tesla
https://www.amd.com/en/products/embedded-automotive-solutions

I won't go into the details here, but we are using exactly the approach
I've outlined to let userspace control the DMA between the different
device in question. I'm one of the main designers of that and our
multimedia and mesa team has up-streamed quite a number of changes for
this project.

I'm not that well into different ARM based solutions because we are just
recently getting results that this starts to work with AMD GPUs, but I'm
pretty sure that the design should be able to handle that as well.

So we have clearly prove that this design works, even with special
requirements which are way more complex than what we are discussing
here. We had cases where we used GStreamer to feed DMA-buf handles into
multiple devices with different format requirements and that seems to
work fine.

Sounds like you have a love/hate relationship with GStreamer. Glad the framework
is working for you too. The

Re: [PATCH] staging: fbtft: Use ARRAY_SIZE() to get argument count

2022-11-04 Thread Deepak R Varma
On Fri, Nov 04, 2022 at 05:31:24PM +0530, Deepak R Varma wrote:
> On Mon, Oct 31, 2022 at 01:05:32PM +0100, Julia Lawall wrote:
> >
> >
> > I took a look, but it's pretty complex.  You could take the code and
> > reorganize it so that it is more readable, and then take the definition of
> > the ARRAY_SIZE macro, to better see what is going on.
> >
> > julia
> >
>
> Hello Greg, Julia,
> I was able to successfully build the fbtft object file for arm architecture as
> well. I used gcc 6.5.0 and 9.5.0 tool chains. It was successful using both. I
> have attached the build log from my machine for your reference.
>
> I am also looking at the .i file and rearrange the expanded macro to 
> understand
> it. However, since it is built successfully, I am not sure if that is truly 
> the
> problem area.
>
> Should I resend the patch and check if it still errors the kernel build bot?
> Anything else I can try?

Looks like the change I proposed is causing nesting inside the write_reg
function due to additional set of { & } brackets for the __VA_ARGS__ symbol.

Am I understanding it right?

>
> Thank you,
> ./drv





Re: [PATCH v2 56/65] clk: ingenic: cgu: Switch to determine_rate

2022-11-04 Thread Paul Cercueil

Hi Maxime,

Le ven. 4 nov. 2022 à 14:18:13 +0100, Maxime Ripard 
 a écrit :

The Ingenic CGU clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name 
implies,

change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far 
less
used, and it doesn't look like there's any obvious user for that 
clock.


So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call 
to

clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.


So it's partly on purpose, partly because I didn't know about 
.determine_rate.


There's nothing odd about having a lonely .set_parent callback; in my 
case the clocks are parented from the device tree.


Having the clocks driver trigger a parent change when requesting a rate 
change sounds very dangerous, IMHO. My MMC controller can be parented 
to the external 48 MHz oscillator, and if the card requests 50 MHz, it 
could switch to one of the PLLs. That works as long as the PLLs don't 
change rate, but if one is configured as driving the CPU clock, it 
becomes messy.
The thing is, the clocks driver has no way to know whether or not it is 
"safe" to use a designated parent.


For that reason, in practice, I never actually want to have a clock 
re-parented - it's almost always a bad idea vs. sticking to the parent 
clock configured in the DTS.




Signed-off-by: Maxime Ripard 
---
 drivers/clk/ingenic/cgu.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index 1f7ba30f5a1b..0c9c8344ad11 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -491,22 +491,23 @@ ingenic_clk_calc_div(struct clk_hw *hw,
return div;
 }

-static long
-ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
-  unsigned long *parent_rate)
+static int ingenic_clk_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
 {
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
 	const struct ingenic_cgu_clk_info *clk_info = 
to_clk_info(ingenic_clk);

unsigned int div = 1;

if (clk_info->type & CGU_CLK_DIV)
-   div = ingenic_clk_calc_div(hw, clk_info, *parent_rate, 
req_rate);
+   div = ingenic_clk_calc_div(hw, clk_info, req->best_parent_rate,
+  req->rate);


Sorry but I'm not sure that this works.

You replace the "parent_rate" with the "best_parent_rate", and that 
means you only check the requested rate vs. the parent with the highest 
frequency, and not vs. the actual parent that will be used.


Cheers,
-Paul


else if (clk_info->type & CGU_CLK_FIXDIV)
div = clk_info->fixdiv.div;
else if (clk_hw_can_set_rate_parent(hw))
-   *parent_rate = req_rate;
+   req->best_parent_rate = req->rate;

-   return DIV_ROUND_UP(*parent_rate, div);
+   req->rate = DIV_ROUND_UP(req->best_parent_rate, div);
+   return 0;
 }

 static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu,
@@ -626,7 +627,7 @@ static const struct clk_ops ingenic_clk_ops = {
.set_parent = ingenic_clk_set_parent,

.recalc_rate = ingenic_clk_recalc_rate,
-   .round_rate = ingenic_clk_round_rate,
+   .determine_rate = ingenic_clk_determine_rate,
.set_rate = ingenic_clk_set_rate,

.enable = ingenic_clk_enable,

--
b4 0.11.0-dev-99e3a





[PATCH v2 65/65] clk: Warn if we register a mux without determine_rate

2022-11-04 Thread Maxime Ripard
The determine_rate hook allows to select the proper parent and its rate
for a given clock configuration. On another hand, set_parent is there to
change the parent of a mux.

Some clocks provide a set_parent hook but don't implement
determine_rate. In such a case, set_parent is pretty much useless since
the clock framework will always assume the current parent is to be used,
and we will thus never change it.

This situation can be solved in two ways:
  - either we don't need to change the parent, and we thus shouldn't
implement set_parent;
  - or we don't want to change the parent, in this case we should set
CLK_SET_RATE_NO_REPARENT;
  - or we're missing a determine_rate implementation.

The latter is probably just an oversight from the driver's author, and
we should thus raise their awareness about the fact that the current
state of the driver is confusing.

It's not clear at this point how many drivers are affected though, so
let's make it a warning instead of an error for now.

Reviewed-by: AngeloGioacchino Del Regno 

Signed-off-by: Maxime Ripard 
---
 drivers/clk/clk.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 495d7497cc43..9eb0343629cc 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3701,6 +3701,13 @@ static int __clk_core_init(struct clk_core *core)
goto out;
}
 
+   if (core->ops->set_parent && !core->ops->determine_rate) {
+   pr_err("%s: %s must implement .set_parent & .determine_rate\n",
+   __func__, core->name);
+   ret = -EINVAL;
+   goto out;
+   }
+
if (core->num_parents > 1 && !core->ops->get_parent) {
pr_err("%s: %s must implement .get_parent as it has multi 
parents\n",
   __func__, core->name);

-- 
b4 0.11.0-dev-99e3a


[PATCH v2 64/65] ASoC: tlv320aic32x4: div: Switch to determine_rate

2022-11-04 Thread Maxime Ripard
The tlv320aic32x4 divider clocks implements a mux with a set_parent
hook, but doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Signed-off-by: Maxime Ripard 
---
 sound/soc/codecs/tlv320aic32x4-clk.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/sound/soc/codecs/tlv320aic32x4-clk.c 
b/sound/soc/codecs/tlv320aic32x4-clk.c
index d8b8ea3eaa12..707c9951fac0 100644
--- a/sound/soc/codecs/tlv320aic32x4-clk.c
+++ b/sound/soc/codecs/tlv320aic32x4-clk.c
@@ -333,16 +333,17 @@ static int clk_aic32x4_div_set_rate(struct clk_hw *hw, 
unsigned long rate,
AIC32X4_DIV_MASK, divisor);
 }
 
-static long clk_aic32x4_div_round_rate(struct clk_hw *hw, unsigned long rate,
-   unsigned long *parent_rate)
+static int clk_aic32x4_div_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
 {
unsigned long divisor;
 
-   divisor = DIV_ROUND_UP(*parent_rate, rate);
+   divisor = DIV_ROUND_UP(req->best_parent_rate, req->rate);
if (divisor > 128)
return -EINVAL;
 
-   return DIV_ROUND_UP(*parent_rate, divisor);
+   req->rate = DIV_ROUND_UP(req->best_parent_rate, divisor);
+   return 0;
 }
 
 static unsigned long clk_aic32x4_div_recalc_rate(struct clk_hw *hw,
@@ -361,7 +362,7 @@ static const struct clk_ops aic32x4_div_ops = {
.prepare = clk_aic32x4_div_prepare,
.unprepare = clk_aic32x4_div_unprepare,
.set_rate = clk_aic32x4_div_set_rate,
-   .round_rate = clk_aic32x4_div_round_rate,
+   .determine_rate = clk_aic32x4_div_determine_rate,
.recalc_rate = clk_aic32x4_div_recalc_rate,
 };
 
@@ -389,7 +390,7 @@ static const struct clk_ops aic32x4_bdiv_ops = {
.set_parent = clk_aic32x4_bdiv_set_parent,
.get_parent = clk_aic32x4_bdiv_get_parent,
.set_rate = clk_aic32x4_div_set_rate,
-   .round_rate = clk_aic32x4_div_round_rate,
+   .determine_rate = clk_aic32x4_div_determine_rate,
.recalc_rate = clk_aic32x4_div_recalc_rate,
 };
 

-- 
b4 0.11.0-dev-99e3a


[PATCH v2 63/65] ASoC: tlv320aic32x4: pll: Switch to determine_rate

2022-11-04 Thread Maxime Ripard
The tlv320aic32x4 PLL clocks implements a mux with a set_parent hook, but
doesn't provide a determine_rate implementation.

This is a bit odd, since set_parent() is there to, as its name implies,
change the parent of a clock. However, the most likely candidate to
trigger that parent change is a call to clk_set_rate(), with
determine_rate() figuring out which parent is the best suited for a
given rate.

The other trigger would be a call to clk_set_parent(), but it's far less
used, and it doesn't look like there's any obvious user for that clock.

So, the set_parent hook is effectively unused, possibly because of an
oversight. However, it could also be an explicit decision by the
original author to avoid any reparenting but through an explicit call to
clk_set_parent().

The driver does implement round_rate() though, which means that we can
change the rate of the clock, but we will never get to change the
parent.

However, It's hard to tell whether it's been done on purpose or not.

Since we'll start mandating a determine_rate() implementation, let's
convert the round_rate() implementation to a determine_rate(), which
will also make the current behavior explicit. And if it was an
oversight, the clock behaviour can be adjusted later on.

Signed-off-by: Maxime Ripard 
---
 sound/soc/codecs/tlv320aic32x4-clk.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/tlv320aic32x4-clk.c 
b/sound/soc/codecs/tlv320aic32x4-clk.c
index 65b72373cb95..d8b8ea3eaa12 100644
--- a/sound/soc/codecs/tlv320aic32x4-clk.c
+++ b/sound/soc/codecs/tlv320aic32x4-clk.c
@@ -205,18 +205,23 @@ static unsigned long clk_aic32x4_pll_recalc_rate(struct 
clk_hw *hw,
return clk_aic32x4_pll_calc_rate(&settings, parent_rate);
 }
 
-static long clk_aic32x4_pll_round_rate(struct clk_hw *hw,
-   unsigned long rate,
-   unsigned long *parent_rate)
+static int clk_aic32x4_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
 {
struct clk_aic32x4_pll_muldiv settings;
+   unsigned long rate;
int ret;
 
-   ret = clk_aic32x4_pll_calc_muldiv(&settings, rate, *parent_rate);
+   ret = clk_aic32x4_pll_calc_muldiv(&settings, req->rate, 
req->best_parent_rate);
if (ret < 0)
-   return 0;
+   return -EINVAL;
 
-   return clk_aic32x4_pll_calc_rate(&settings, *parent_rate);
+   rate = clk_aic32x4_pll_calc_rate(&settings, req->best_parent_rate);
+   if (rate < 0)
+   return rate;
+
+   req->rate = rate;
+   return 0;
 }
 
 static int clk_aic32x4_pll_set_rate(struct clk_hw *hw,
@@ -267,7 +272,7 @@ static const struct clk_ops aic32x4_pll_ops = {
.unprepare = clk_aic32x4_pll_unprepare,
.is_prepared = clk_aic32x4_pll_is_prepared,
.recalc_rate = clk_aic32x4_pll_recalc_rate,
-   .round_rate = clk_aic32x4_pll_round_rate,
+   .determine_rate = clk_aic32x4_pll_determine_rate,
.set_rate = clk_aic32x4_pll_set_rate,
.set_parent = clk_aic32x4_pll_set_parent,
.get_parent = clk_aic32x4_pll_get_parent,

-- 
b4 0.11.0-dev-99e3a


Re: [PATCH v1 5/5] arm64: dts: qcom: sm8450-hdk: Enable HDMI Display

2022-11-04 Thread Krzysztof Kozlowski
On 04/11/2022 09:13, Dmitry Baryshkov wrote:
> From: Vinod Koul 
> 
> Add the HDMI display nodes and link it to DSI. Also enable missing dispcc
> nodes
> 
> Signed-off-by: Vinod Koul 
> Signed-off-by: Dmitry Baryshkov 

Thank you for your patch. There is something to discuss/improve.

> +&dispcc {
> + status = "okay";
> +};
> +
>  &dsi0 {
>   status = "okay";
>   vdda-supply = <&vreg_l6b_1p2>;
> +
> + ports {
> + port@1 {
> + endpoint {
> + remote-endpoint = <<9611_a>;
> + data-lanes = <0 1 2 3>;
> + };
> + };
> + };
> +

Drop blank line.

Reviewed-by: Krzysztof Kozlowski 

Best regards,
Krzysztof



[PATCH v3 1/7] vfio/ccw: create a parent struct

2022-11-04 Thread Eric Farman
Move the stuff associated with the mdev parent (and thus the
subchannel struct) into its own struct, and leave the rest in
the existing private structure.

The subchannel will point to the parent, and the parent will point
to the private, for the areas where one or both are needed. Further
separation of these structs will follow.

Signed-off-by: Eric Farman 
Reviewed-by: Matthew Rosato 
---
 drivers/s390/cio/vfio_ccw_drv.c | 98 +++--
 drivers/s390/cio/vfio_ccw_ops.c |  8 ++-
 drivers/s390/cio/vfio_ccw_private.h | 20 --
 3 files changed, 101 insertions(+), 25 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 7f5402fe857a..444b32047397 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -36,10 +36,19 @@ debug_info_t *vfio_ccw_debug_trace_id;
  */
 int vfio_ccw_sch_quiesce(struct subchannel *sch)
 {
-   struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
+   struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev);
+   struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev);
DECLARE_COMPLETION_ONSTACK(completion);
int iretry, ret = 0;
 
+   /*
+* Probably an impossible situation, after being called through
+* FSM callbacks. But in the event it did, register a warning
+* and return as if things were fine.
+*/
+   if (WARN_ON(!private))
+   return 0;
+
iretry = 255;
do {
 
@@ -121,7 +130,23 @@ static void vfio_ccw_crw_todo(struct work_struct *work)
  */
 static void vfio_ccw_sch_irq(struct subchannel *sch)
 {
-   struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
+   struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev);
+   struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev);
+
+   /*
+* The subchannel should still be disabled at this point,
+* so an interrupt would be quite surprising. As with an
+* interrupt while the FSM is closed, let's attempt to
+* disable the subchannel again.
+*/
+   if (!private) {
+   VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: unexpected interrupt\n",
+  sch->schid.cssid, sch->schid.ssid,
+  sch->schid.sch_no);
+
+   cio_disable_subchannel(sch);
+   return;
+   }
 
inc_irq_stat(IRQIO_CIO);
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
@@ -201,10 +226,19 @@ static void vfio_ccw_free_private(struct vfio_ccw_private 
*private)
mutex_destroy(&private->io_mutex);
kfree(private);
 }
+
+static void vfio_ccw_free_parent(struct device *dev)
+{
+   struct vfio_ccw_parent *parent = container_of(dev, struct 
vfio_ccw_parent, dev);
+
+   kfree(parent);
+}
+
 static int vfio_ccw_sch_probe(struct subchannel *sch)
 {
struct pmcw *pmcw = &sch->schib.pmcw;
struct vfio_ccw_private *private;
+   struct vfio_ccw_parent *parent;
int ret = -ENOMEM;
 
if (pmcw->qf) {
@@ -213,38 +247,58 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
return -ENODEV;
}
 
+   parent = kzalloc(sizeof(*parent), GFP_KERNEL);
+   if (!parent)
+   return -ENOMEM;
+
+   dev_set_name(&parent->dev, "parent");
+   parent->dev.parent = &sch->dev;
+   parent->dev.release = &vfio_ccw_free_parent;
+   ret = device_register(&parent->dev);
+   if (ret)
+   goto out_free;
+
private = vfio_ccw_alloc_private(sch);
-   if (IS_ERR(private))
+   if (IS_ERR(private)) {
+   device_unregister(&parent->dev);
return PTR_ERR(private);
+   }
 
-   dev_set_drvdata(&sch->dev, private);
+   dev_set_drvdata(&sch->dev, parent);
+   dev_set_drvdata(&parent->dev, private);
 
-   private->mdev_type.sysfs_name = "io";
-   private->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)";
-   private->mdev_types[0] = &private->mdev_type;
-   ret = mdev_register_parent(&private->parent, &sch->dev,
+   parent->mdev_type.sysfs_name = "io";
+   parent->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)";
+   parent->mdev_types[0] = &parent->mdev_type;
+   ret = mdev_register_parent(&parent->parent, &sch->dev,
   &vfio_ccw_mdev_driver,
-  private->mdev_types, 1);
+  parent->mdev_types, 1);
if (ret)
-   goto out_free;
+   goto out_unreg;
 
VFIO_CCW_MSG_EVENT(4, "bound to subchannel %x.%x.%04x\n",
   sch->schid.cssid, sch->schid.ssid,
   sch->schid.sch_no);
return 0;
 
+out_unreg:
+   device_unregister(&parent->dev);
 out_free:
+   dev_set_drvdata(&parent->dev, NULL);
dev_set_drvdata(&sch->dev,

[PATCH v3 7/7] vfio: Remove vfio_free_device

2022-11-04 Thread Eric Farman
With the "mess" sorted out, we should be able to inline the
vfio_free_device call introduced by commit cb9ff3f3b84c
("vfio: Add helpers for unifying vfio_device life cycle")
and remove them from driver release callbacks.

Signed-off-by: Eric Farman 
Reviewed-by: Jason Gunthorpe 
Reviewed-by: Kevin Tian 
Reviewed-by: Cornelia Huck 
Reviewed-by: Tony Krowiak   # vfio-ap part
Acked-by: Alex Williamson 
Reviewed-by: Matthew Rosato 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c  |  1 -
 drivers/s390/cio/vfio_ccw_ops.c   |  2 --
 drivers/s390/crypto/vfio_ap_ops.c |  6 --
 drivers/vfio/fsl-mc/vfio_fsl_mc.c |  1 -
 drivers/vfio/pci/vfio_pci_core.c  |  1 -
 drivers/vfio/platform/vfio_amba.c |  1 -
 drivers/vfio/platform/vfio_platform.c |  1 -
 drivers/vfio/vfio_main.c  | 22 --
 include/linux/vfio.h  |  1 -
 samples/vfio-mdev/mbochs.c|  1 -
 samples/vfio-mdev/mdpy.c  |  1 -
 samples/vfio-mdev/mtty.c  |  1 -
 12 files changed, 4 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 7a45e5360caf..eee6805e67de 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1461,7 +1461,6 @@ static void intel_vgpu_release_dev(struct vfio_device 
*vfio_dev)
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
 
intel_gvt_destroy_vgpu(vgpu);
-   vfio_free_device(vfio_dev);
 }
 
 static const struct vfio_device_ops intel_vgpu_dev_ops = {
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 1155f8bcedd9..598a3814d428 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -143,8 +143,6 @@ static void vfio_ccw_mdev_release_dev(struct vfio_device 
*vdev)
kmem_cache_free(vfio_ccw_io_region, private->io_region);
kfree(private->cp.guest_cp);
mutex_destroy(&private->io_mutex);
-
-   vfio_free_device(vdev);
 }
 
 static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c 
b/drivers/s390/crypto/vfio_ap_ops.c
index 0b4cc8c597ae..f108c0f14712 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -765,11 +765,6 @@ static void vfio_ap_mdev_unlink_fr_queues(struct 
ap_matrix_mdev *matrix_mdev)
}
 }
 
-static void vfio_ap_mdev_release_dev(struct vfio_device *vdev)
-{
-   vfio_free_device(vdev);
-}
-
 static void vfio_ap_mdev_remove(struct mdev_device *mdev)
 {
struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(&mdev->dev);
@@ -1784,7 +1779,6 @@ static const struct attribute_group vfio_queue_attr_group 
= {
 
 static const struct vfio_device_ops vfio_ap_matrix_dev_ops = {
.init = vfio_ap_mdev_init_dev,
-   .release = vfio_ap_mdev_release_dev,
.open_device = vfio_ap_mdev_open_device,
.close_device = vfio_ap_mdev_close_device,
.ioctl = vfio_ap_mdev_ioctl,
diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c 
b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
index b16874e913e4..7b8889f55007 100644
--- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c
+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
@@ -568,7 +568,6 @@ static void vfio_fsl_mc_release_dev(struct vfio_device 
*core_vdev)
 
vfio_fsl_uninit_device(vdev);
mutex_destroy(&vdev->igate);
-   vfio_free_device(core_vdev);
 }
 
 static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index badc9d828cac..9be2d5be5d95 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -2109,7 +2109,6 @@ void vfio_pci_core_release_dev(struct vfio_device 
*core_vdev)
mutex_destroy(&vdev->vma_lock);
kfree(vdev->region);
kfree(vdev->pm_save);
-   vfio_free_device(core_vdev);
 }
 EXPORT_SYMBOL_GPL(vfio_pci_core_release_dev);
 
diff --git a/drivers/vfio/platform/vfio_amba.c 
b/drivers/vfio/platform/vfio_amba.c
index eaea63e5294c..18faf2678b99 100644
--- a/drivers/vfio/platform/vfio_amba.c
+++ b/drivers/vfio/platform/vfio_amba.c
@@ -95,7 +95,6 @@ static void vfio_amba_release_dev(struct vfio_device 
*core_vdev)
 
vfio_platform_release_common(vdev);
kfree(vdev->name);
-   vfio_free_device(core_vdev);
 }
 
 static void vfio_amba_remove(struct amba_device *adev)
diff --git a/drivers/vfio/platform/vfio_platform.c 
b/drivers/vfio/platform/vfio_platform.c
index 82cedcebfd90..9910451dc341 100644
--- a/drivers/vfio/platform/vfio_platform.c
+++ b/drivers/vfio/platform/vfio_platform.c
@@ -83,7 +83,6 @@ static void vfio_platform_release_dev(struct vfio_device 
*core_vdev)
container_of(core_vdev, struct vfio_platform_device, vdev);
 
vfio_platform_release_common(vdev);
-   vfio_free_device(core_vdev);
 }
 
 static int vfio_platform_remove(struct platform_device *pdev)
diff --git a/drivers/vfio/vfio_main.c b/driv

[PATCH v3 6/7] vfio/ccw: replace vfio_init_device with _alloc_

2022-11-04 Thread Eric Farman
Now that we have a reasonable separation of structs that follow
the subchannel and mdev lifecycles, there's no reason we can't
call the official vfio_alloc_device routine for our private data,
and behave like everyone else.

Signed-off-by: Eric Farman 
Reviewed-by: Kevin Tian 
Acked-by: Alex Williamson 
Reviewed-by: Matthew Rosato 
---
 drivers/s390/cio/vfio_ccw_drv.c | 18 --
 drivers/s390/cio/vfio_ccw_ops.c | 28 ++--
 drivers/s390/cio/vfio_ccw_private.h |  2 --
 drivers/vfio/vfio_main.c| 10 +-
 include/linux/vfio.h|  2 --
 5 files changed, 23 insertions(+), 37 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 9fbd1b27a1ac..c2a65808605a 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -152,24 +152,6 @@ static void vfio_ccw_sch_irq(struct subchannel *sch)
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
 }
 
-void vfio_ccw_free_private(struct vfio_ccw_private *private)
-{
-   struct vfio_ccw_crw *crw, *temp;
-
-   list_for_each_entry_safe(crw, temp, &private->crw, next) {
-   list_del(&crw->next);
-   kfree(crw);
-   }
-
-   kmem_cache_free(vfio_ccw_crw_region, private->crw_region);
-   kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
-   kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
-   kmem_cache_free(vfio_ccw_io_region, private->io_region);
-   kfree(private->cp.guest_cp);
-   mutex_destroy(&private->io_mutex);
-   kfree(private);
-}
-
 static void vfio_ccw_free_parent(struct device *dev)
 {
struct vfio_ccw_parent *parent = container_of(dev, struct 
vfio_ccw_parent, dev);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 8a929a9cf3c6..1155f8bcedd9 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -102,15 +102,10 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
struct vfio_ccw_private *private;
int ret;
 
-   private = kzalloc(sizeof(*private), GFP_KERNEL);
-   if (!private)
-   return -ENOMEM;
-
-   ret = vfio_init_device(&private->vdev, &mdev->dev, &vfio_ccw_dev_ops);
-   if (ret) {
-   kfree(private);
-   return ret;
-   }
+   private = vfio_alloc_device(vfio_ccw_private, vdev, &mdev->dev,
+   &vfio_ccw_dev_ops);
+   if (IS_ERR(private))
+   return PTR_ERR(private);
 
dev_set_drvdata(&parent->dev, private);
 
@@ -135,8 +130,21 @@ static void vfio_ccw_mdev_release_dev(struct vfio_device 
*vdev)
 {
struct vfio_ccw_private *private =
container_of(vdev, struct vfio_ccw_private, vdev);
+   struct vfio_ccw_crw *crw, *temp;
+
+   list_for_each_entry_safe(crw, temp, &private->crw, next) {
+   list_del(&crw->next);
+   kfree(crw);
+   }
+
+   kmem_cache_free(vfio_ccw_crw_region, private->crw_region);
+   kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
+   kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
+   kmem_cache_free(vfio_ccw_io_region, private->io_region);
+   kfree(private->cp.guest_cp);
+   mutex_destroy(&private->io_mutex);
 
-   vfio_ccw_free_private(private);
+   vfio_free_device(vdev);
 }
 
 static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
diff --git a/drivers/s390/cio/vfio_ccw_private.h 
b/drivers/s390/cio/vfio_ccw_private.h
index 2278fd38d34e..b441ae6700fd 100644
--- a/drivers/s390/cio/vfio_ccw_private.h
+++ b/drivers/s390/cio/vfio_ccw_private.h
@@ -131,8 +131,6 @@ int vfio_ccw_sch_quiesce(struct subchannel *sch);
 void vfio_ccw_sch_io_todo(struct work_struct *work);
 void vfio_ccw_crw_todo(struct work_struct *work);
 
-void vfio_ccw_free_private(struct vfio_ccw_private *private);
-
 extern struct mdev_driver vfio_ccw_mdev_driver;
 
 /*
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 2d168793d4e1..2901b8ad5be9 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -348,6 +348,9 @@ static void vfio_device_release(struct device *dev)
device->ops->release(device);
 }
 
+static int vfio_init_device(struct vfio_device *device, struct device *dev,
+   const struct vfio_device_ops *ops);
+
 /*
  * Allocate and initialize vfio_device so it can be registered to vfio
  * core.
@@ -386,11 +389,9 @@ EXPORT_SYMBOL_GPL(_vfio_alloc_device);
 
 /*
  * Initialize a vfio_device so it can be registered to vfio core.
- *
- * Only vfio-ccw driver should call this interface.
  */
-int vfio_init_device(struct vfio_device *device, struct device *dev,
-const struct vfio_device_ops *ops)
+static int vfio_init_device(struct vfio_device *device, struct device *dev,
+   const struct vfio_device_ops 

[PATCH v3 2/7] vfio/ccw: remove private->sch

2022-11-04 Thread Eric Farman
These places all rely on the ability to jump from a private
struct back to the subchannel struct. Rather than keeping a
copy in our back pocket, let's use the relationship provided
by the vfio_device embedded within the private.

Signed-off-by: Eric Farman 
Reviewed-by: Matthew Rosato 
---
 drivers/s390/cio/vfio_ccw_chp.c |  5 +++--
 drivers/s390/cio/vfio_ccw_drv.c |  3 +--
 drivers/s390/cio/vfio_ccw_fsm.c | 27 ---
 drivers/s390/cio/vfio_ccw_ops.c | 12 ++--
 drivers/s390/cio/vfio_ccw_private.h |  7 ---
 5 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_chp.c b/drivers/s390/cio/vfio_ccw_chp.c
index 13b26a1c7988..d3f3a611f95b 100644
--- a/drivers/s390/cio/vfio_ccw_chp.c
+++ b/drivers/s390/cio/vfio_ccw_chp.c
@@ -16,6 +16,7 @@ static ssize_t vfio_ccw_schib_region_read(struct 
vfio_ccw_private *private,
  char __user *buf, size_t count,
  loff_t *ppos)
 {
+   struct subchannel *sch = to_subchannel(private->vdev.dev->parent);
unsigned int i = VFIO_CCW_OFFSET_TO_INDEX(*ppos) - VFIO_CCW_NUM_REGIONS;
loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK;
struct ccw_schib_region *region;
@@ -27,12 +28,12 @@ static ssize_t vfio_ccw_schib_region_read(struct 
vfio_ccw_private *private,
mutex_lock(&private->io_mutex);
region = private->region[i].data;
 
-   if (cio_update_schib(private->sch)) {
+   if (cio_update_schib(sch)) {
ret = -ENODEV;
goto out;
}
 
-   memcpy(region, &private->sch->schib, sizeof(*region));
+   memcpy(region, &sch->schib, sizeof(*region));
 
if (copy_to_user(buf, (void *)region + pos, count)) {
ret = -EFAULT;
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 444b32047397..2c680a556383 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -160,7 +160,6 @@ static struct vfio_ccw_private 
*vfio_ccw_alloc_private(struct subchannel *sch)
if (!private)
return ERR_PTR(-ENOMEM);
 
-   private->sch = sch;
mutex_init(&private->io_mutex);
private->state = VFIO_CCW_STATE_STANDBY;
INIT_LIST_HEAD(&private->crw);
@@ -395,7 +394,7 @@ static int vfio_ccw_chp_event(struct subchannel *sch,
if (!private || !mask)
return 0;
 
-   trace_vfio_ccw_chp_event(private->sch->schid, mask, event);
+   trace_vfio_ccw_chp_event(sch->schid, mask, event);
VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: mask=0x%x event=%d\n",
   sch->schid.cssid,
   sch->schid.ssid, sch->schid.sch_no,
diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c
index a59c758869f8..e67fad897af3 100644
--- a/drivers/s390/cio/vfio_ccw_fsm.c
+++ b/drivers/s390/cio/vfio_ccw_fsm.c
@@ -18,15 +18,13 @@
 
 static int fsm_io_helper(struct vfio_ccw_private *private)
 {
-   struct subchannel *sch;
+   struct subchannel *sch = to_subchannel(private->vdev.dev->parent);
union orb *orb;
int ccode;
__u8 lpm;
unsigned long flags;
int ret;
 
-   sch = private->sch;
-
spin_lock_irqsave(sch->lock, flags);
 
orb = cp_get_orb(&private->cp, (u32)(addr_t)sch, sch->lpm);
@@ -80,13 +78,11 @@ static int fsm_io_helper(struct vfio_ccw_private *private)
 
 static int fsm_do_halt(struct vfio_ccw_private *private)
 {
-   struct subchannel *sch;
+   struct subchannel *sch = to_subchannel(private->vdev.dev->parent);
unsigned long flags;
int ccode;
int ret;
 
-   sch = private->sch;
-
spin_lock_irqsave(sch->lock, flags);
 
VFIO_CCW_TRACE_EVENT(2, "haltIO");
@@ -121,13 +117,11 @@ static int fsm_do_halt(struct vfio_ccw_private *private)
 
 static int fsm_do_clear(struct vfio_ccw_private *private)
 {
-   struct subchannel *sch;
+   struct subchannel *sch = to_subchannel(private->vdev.dev->parent);
unsigned long flags;
int ccode;
int ret;
 
-   sch = private->sch;
-
spin_lock_irqsave(sch->lock, flags);
 
VFIO_CCW_TRACE_EVENT(2, "clearIO");
@@ -160,7 +154,7 @@ static int fsm_do_clear(struct vfio_ccw_private *private)
 static void fsm_notoper(struct vfio_ccw_private *private,
enum vfio_ccw_event event)
 {
-   struct subchannel *sch = private->sch;
+   struct subchannel *sch = to_subchannel(private->vdev.dev->parent);
 
VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: notoper event %x state %x\n",
   sch->schid.cssid,
@@ -228,7 +222,7 @@ static void fsm_async_retry(struct vfio_ccw_private 
*private,
 static void fsm_disabled_irq(struct vfio_ccw_private *private,
 enum vfio_ccw_event event)
 {
-   struct subchannel *sch = private->sch;
+   str

[PATCH v3 5/7] vfio/ccw: remove release completion

2022-11-04 Thread Eric Farman
There's enough separation between the parent and private structs now,
that it is fine to remove the release completion hack.

Signed-off-by: Eric Farman 
Reviewed-by: Kevin Tian 
Reviewed-by: Matthew Rosato 
---
 drivers/s390/cio/vfio_ccw_ops.c | 14 +-
 drivers/s390/cio/vfio_ccw_private.h |  3 ---
 2 files changed, 1 insertion(+), 16 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index e45d4acb109b..8a929a9cf3c6 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -54,7 +54,6 @@ static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev)
INIT_LIST_HEAD(&private->crw);
INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
-   init_completion(&private->release_comp);
 
private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),
   GFP_KERNEL);
@@ -137,7 +136,7 @@ static void vfio_ccw_mdev_release_dev(struct vfio_device 
*vdev)
struct vfio_ccw_private *private =
container_of(vdev, struct vfio_ccw_private, vdev);
 
-   complete(&private->release_comp);
+   vfio_ccw_free_private(private);
 }
 
 static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
@@ -155,17 +154,6 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
 
dev_set_drvdata(&parent->dev, NULL);
vfio_put_device(&private->vdev);
-   /*
-* Wait for all active references on mdev are released so it
-* is safe to defer kfree() to a later point.
-*
-* TODO: the clean fix is to split parent/mdev info from ccw
-* private structure so each can be managed in its own life
-* cycle.
-*/
-   wait_for_completion(&private->release_comp);
-
-   vfio_ccw_free_private(private);
 }
 
 static int vfio_ccw_mdev_open_device(struct vfio_device *vdev)
diff --git a/drivers/s390/cio/vfio_ccw_private.h 
b/drivers/s390/cio/vfio_ccw_private.h
index 747aba5f5272..2278fd38d34e 100644
--- a/drivers/s390/cio/vfio_ccw_private.h
+++ b/drivers/s390/cio/vfio_ccw_private.h
@@ -102,7 +102,6 @@ struct vfio_ccw_parent {
  * @req_trigger: eventfd ctx for signaling userspace to return device
  * @io_work: work for deferral process of I/O handling
  * @crw_work: work for deferral process of CRW handling
- * @release_comp: synchronization helper for vfio device release
  */
 struct vfio_ccw_private {
struct vfio_device vdev;
@@ -126,8 +125,6 @@ struct vfio_ccw_private {
struct eventfd_ctx  *req_trigger;
struct work_struct  io_work;
struct work_struct  crw_work;
-
-   struct completion   release_comp;
 } __aligned(8);
 
 int vfio_ccw_sch_quiesce(struct subchannel *sch);
-- 
2.34.1



[PATCH v3 4/7] vfio/ccw: move private to mdev lifecycle

2022-11-04 Thread Eric Farman
Now that the mdev parent data is split out into its own struct,
it is safe to move the remaining private data to follow the
mdev probe/remove lifecycle. The mdev parent data will remain
where it is, and follow the subchannel and the css driver
interfaces.

Signed-off-by: Eric Farman 
Reviewed-by: Matthew Rosato 
---
 drivers/s390/cio/vfio_ccw_drv.c | 16 +---
 drivers/s390/cio/vfio_ccw_ops.c | 26 +-
 drivers/s390/cio/vfio_ccw_private.h |  2 ++
 3 files changed, 16 insertions(+), 28 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index fbc26338ceab..9fbd1b27a1ac 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -152,7 +152,7 @@ static void vfio_ccw_sch_irq(struct subchannel *sch)
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
 }
 
-static void vfio_ccw_free_private(struct vfio_ccw_private *private)
+void vfio_ccw_free_private(struct vfio_ccw_private *private)
 {
struct vfio_ccw_crw *crw, *temp;
 
@@ -180,7 +180,6 @@ static void vfio_ccw_free_parent(struct device *dev)
 static int vfio_ccw_sch_probe(struct subchannel *sch)
 {
struct pmcw *pmcw = &sch->schib.pmcw;
-   struct vfio_ccw_private *private;
struct vfio_ccw_parent *parent;
int ret = -ENOMEM;
 
@@ -201,14 +200,7 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
if (ret)
goto out_free;
 
-   private = kzalloc(sizeof(*private), GFP_KERNEL);
-   if (!private) {
-   device_unregister(&parent->dev);
-   return -ENOMEM;
-   }
-
dev_set_drvdata(&sch->dev, parent);
-   dev_set_drvdata(&parent->dev, private);
 
parent->mdev_type.sysfs_name = "io";
parent->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)";
@@ -227,25 +219,19 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
 out_unreg:
device_unregister(&parent->dev);
 out_free:
-   dev_set_drvdata(&parent->dev, NULL);
dev_set_drvdata(&sch->dev, NULL);
-   if (private)
-   vfio_ccw_free_private(private);
return ret;
 }
 
 static void vfio_ccw_sch_remove(struct subchannel *sch)
 {
struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev);
-   struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev);
 
mdev_unregister_parent(&parent->parent);
 
device_unregister(&parent->dev);
dev_set_drvdata(&sch->dev, NULL);
 
-   vfio_ccw_free_private(private);
-
VFIO_CCW_MSG_EVENT(4, "unbound from subchannel %x.%x.%04x\n",
   sch->schid.cssid, sch->schid.ssid,
   sch->schid.sch_no);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index eb0b8cc210bb..e45d4acb109b 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -100,15 +100,20 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
 {
struct subchannel *sch = to_subchannel(mdev->dev.parent);
struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev);
-   struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev);
+   struct vfio_ccw_private *private;
int ret;
 
-   if (private->state == VFIO_CCW_STATE_NOT_OPER)
-   return -ENODEV;
+   private = kzalloc(sizeof(*private), GFP_KERNEL);
+   if (!private)
+   return -ENOMEM;
 
ret = vfio_init_device(&private->vdev, &mdev->dev, &vfio_ccw_dev_ops);
-   if (ret)
+   if (ret) {
+   kfree(private);
return ret;
+   }
+
+   dev_set_drvdata(&parent->dev, private);
 
VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: create\n",
   sch->schid.cssid,
@@ -122,6 +127,7 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
return 0;
 
 err_put_vdev:
+   dev_set_drvdata(&parent->dev, NULL);
vfio_put_device(&private->vdev);
return ret;
 }
@@ -131,15 +137,6 @@ static void vfio_ccw_mdev_release_dev(struct vfio_device 
*vdev)
struct vfio_ccw_private *private =
container_of(vdev, struct vfio_ccw_private, vdev);
 
-   /*
-* We cannot free vfio_ccw_private here because it includes
-* parent info which must be free'ed by css driver.
-*
-* Use a workaround by memset'ing the core device part and
-* then notifying the remove path that all active references
-* to this device have been released.
-*/
-   memset(vdev, 0, sizeof(*vdev));
complete(&private->release_comp);
 }
 
@@ -156,6 +153,7 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
 
vfio_unregister_group_dev(&private->vdev);
 
+   dev_set_drvdata(&parent->dev, NULL);
vfio_put_device(&private->vdev);
/*
 * Wait for all active references on mdev are released so it
@@ -166,6 +164,8 @@ static 

[PATCH v3 0/7] vfio-ccw parent rework

2022-11-04 Thread Eric Farman
Hi Alex,

Here's the (last?) update to the vfio-ccw lifecycle changes that I've sent
recently, and were previously discussed at various points [1][2].

Patches 1-5 rework the behavior of the vfio-ccw driver's private struct.
In summary, the mdev pieces are split out of vfio_ccw_private and into a
new vfio_ccw_parent struct that will continue to follow today's lifecycle.
The remainder (bulk) of the private struct moves to follow the mdev
probe/remove pair. There's opportunity for further separation of the
things in the private struct, which would simplify some of the vfio-ccw
code, but it got too hairy as I started that. Once vfio-ccw is no longer
considered unique, those cleanups can happen at our leisure. 

Patch 6 removes the trickery where vfio-ccw uses vfio_init_device instead of
vfio_alloc_device, and thus removes vfio_init_device from the outside world.

Patch 7 removes vfio_free_device from vfio-ccw and the other drivers (hello,
CC list!), letting it be handled by vfio_device_release directly.

I believe this covers everything in this space; let me know if not!

Thanks,
Eric

[1] https://lore.kernel.org/kvm/0-v3-57c1502c62fd+2190-ccw_mdev_...@nvidia.com/
[2] https://lore.kernel.org/kvm/20220602171948.2790690-1-far...@linux.ibm.com/

v2->v3:
 - [MR] Added r-b to remaining patches (Thank you!)
 - Patch 1:
   [gfx checkpatch] Whitespace
   [EF] Remove put_device(&parent->dev)
   [MR] Fix error exit when alloc of parent fails
   [MR] Check for !private on sch_probe error path
 - Patch 3:
   [EF] Fix error exit when alloc of private fails
 - Patch 6:
   [AW] Added ack (Thank you!)
 - Patch 7:
   [CH, AK] Added r-b (Thank you!)
   [AW] Added ack (Thank you!)
v2: https://lore.kernel.org/kvm/20221102150152.2521475-1-far...@linux.ibm.com/
v1: https://lore.kernel.org/kvm/20221019162135.798901-1-far...@linux.ibm.com/

Eric Farman (7):
  vfio/ccw: create a parent struct
  vfio/ccw: remove private->sch
  vfio/ccw: move private initialization to callback
  vfio/ccw: move private to mdev lifecycle
  vfio/ccw: remove release completion
  vfio/ccw: replace vfio_init_device with _alloc_
  vfio: Remove vfio_free_device

 drivers/gpu/drm/i915/gvt/kvmgt.c  |   1 -
 drivers/s390/cio/vfio_ccw_chp.c   |   5 +-
 drivers/s390/cio/vfio_ccw_drv.c   | 173 +++---
 drivers/s390/cio/vfio_ccw_fsm.c   |  27 ++--
 drivers/s390/cio/vfio_ccw_ops.c   | 107 +++-
 drivers/s390/cio/vfio_ccw_private.h   |  37 --
 drivers/s390/crypto/vfio_ap_ops.c |   6 -
 drivers/vfio/fsl-mc/vfio_fsl_mc.c |   1 -
 drivers/vfio/pci/vfio_pci_core.c  |   1 -
 drivers/vfio/platform/vfio_amba.c |   1 -
 drivers/vfio/platform/vfio_platform.c |   1 -
 drivers/vfio/vfio_main.c  |  32 ++---
 include/linux/vfio.h  |   3 -
 samples/vfio-mdev/mbochs.c|   1 -
 samples/vfio-mdev/mdpy.c  |   1 -
 samples/vfio-mdev/mtty.c  |   1 -
 16 files changed, 196 insertions(+), 202 deletions(-)

-- 
2.34.1



[PATCH v3 3/7] vfio/ccw: move private initialization to callback

2022-11-04 Thread Eric Farman
There's already a device initialization callback that is used to
initialize the release completion workaround that was introduced
by commit ebb72b765fb49 ("vfio/ccw: Use the new device life cycle
helpers").

Move the other elements of the vfio_ccw_private struct that
require distinct initialization over to that routine.

With that done, the vfio_ccw_alloc_private routine only does a
kzalloc, so fold it inline.

Signed-off-by: Eric Farman 
Reviewed-by: Matthew Rosato 
---
 drivers/s390/cio/vfio_ccw_drv.c | 74 -
 drivers/s390/cio/vfio_ccw_ops.c | 43 +
 drivers/s390/cio/vfio_ccw_private.h |  7 ++-
 3 files changed, 58 insertions(+), 66 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 2c680a556383..fbc26338ceab 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -23,10 +23,10 @@
 #include "vfio_ccw_private.h"
 
 struct workqueue_struct *vfio_ccw_work_q;
-static struct kmem_cache *vfio_ccw_io_region;
-static struct kmem_cache *vfio_ccw_cmd_region;
-static struct kmem_cache *vfio_ccw_schib_region;
-static struct kmem_cache *vfio_ccw_crw_region;
+struct kmem_cache *vfio_ccw_io_region;
+struct kmem_cache *vfio_ccw_cmd_region;
+struct kmem_cache *vfio_ccw_schib_region;
+struct kmem_cache *vfio_ccw_crw_region;
 
 debug_info_t *vfio_ccw_debug_msg_id;
 debug_info_t *vfio_ccw_debug_trace_id;
@@ -79,7 +79,7 @@ int vfio_ccw_sch_quiesce(struct subchannel *sch)
return ret;
 }
 
-static void vfio_ccw_sch_io_todo(struct work_struct *work)
+void vfio_ccw_sch_io_todo(struct work_struct *work)
 {
struct vfio_ccw_private *private;
struct irb *irb;
@@ -115,7 +115,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
eventfd_signal(private->io_trigger, 1);
 }
 
-static void vfio_ccw_crw_todo(struct work_struct *work)
+void vfio_ccw_crw_todo(struct work_struct *work)
 {
struct vfio_ccw_private *private;
 
@@ -152,62 +152,6 @@ static void vfio_ccw_sch_irq(struct subchannel *sch)
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
 }
 
-static struct vfio_ccw_private *vfio_ccw_alloc_private(struct subchannel *sch)
-{
-   struct vfio_ccw_private *private;
-
-   private = kzalloc(sizeof(*private), GFP_KERNEL);
-   if (!private)
-   return ERR_PTR(-ENOMEM);
-
-   mutex_init(&private->io_mutex);
-   private->state = VFIO_CCW_STATE_STANDBY;
-   INIT_LIST_HEAD(&private->crw);
-   INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
-   INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
-
-   private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),
-  GFP_KERNEL);
-   if (!private->cp.guest_cp)
-   goto out_free_private;
-
-   private->io_region = kmem_cache_zalloc(vfio_ccw_io_region,
-  GFP_KERNEL | GFP_DMA);
-   if (!private->io_region)
-   goto out_free_cp;
-
-   private->cmd_region = kmem_cache_zalloc(vfio_ccw_cmd_region,
-   GFP_KERNEL | GFP_DMA);
-   if (!private->cmd_region)
-   goto out_free_io;
-
-   private->schib_region = kmem_cache_zalloc(vfio_ccw_schib_region,
- GFP_KERNEL | GFP_DMA);
-
-   if (!private->schib_region)
-   goto out_free_cmd;
-
-   private->crw_region = kmem_cache_zalloc(vfio_ccw_crw_region,
-   GFP_KERNEL | GFP_DMA);
-
-   if (!private->crw_region)
-   goto out_free_schib;
-   return private;
-
-out_free_schib:
-   kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
-out_free_cmd:
-   kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
-out_free_io:
-   kmem_cache_free(vfio_ccw_io_region, private->io_region);
-out_free_cp:
-   kfree(private->cp.guest_cp);
-out_free_private:
-   mutex_destroy(&private->io_mutex);
-   kfree(private);
-   return ERR_PTR(-ENOMEM);
-}
-
 static void vfio_ccw_free_private(struct vfio_ccw_private *private)
 {
struct vfio_ccw_crw *crw, *temp;
@@ -257,10 +201,10 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
if (ret)
goto out_free;
 
-   private = vfio_ccw_alloc_private(sch);
-   if (IS_ERR(private)) {
+   private = kzalloc(sizeof(*private), GFP_KERNEL);
+   if (!private) {
device_unregister(&parent->dev);
-   return PTR_ERR(private);
+   return -ENOMEM;
}
 
dev_set_drvdata(&sch->dev, parent);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 79c50cb7dcb8..eb0b8cc210bb 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -49,8 +49,51 @@ static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev)

Re: [PATCH v1 4/5] arm64: dts: qcom: sm8450-hdk: Add LT9611uxc HDMI bridge

2022-11-04 Thread Krzysztof Kozlowski
On 04/11/2022 09:13, Dmitry Baryshkov wrote:
> From: Vinod Koul 
> 
> Add the LT9611uxc DSI-HDMI bridge and supplies
> 
> Signed-off-by: Vinod Koul 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  arch/arm64/boot/dts/qcom/sm8450-hdk.dts | 61 +
>  1 file changed, 61 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts 
> b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
> index e1a4cf1ee51d..9522dd29a38a 100644
> --- a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
> +++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
> @@ -20,6 +20,28 @@ chosen {
>   stdout-path = "serial0:115200n8";
>   };
>  
> + lt9611_1v2: lt9611-vdd12-regulator {

Node name: drop lt9611

> + compatible = "regulator-fixed";
> + regulator-name = "LT9611_1V2";
> +
> + vin-supply = <&vph_pwr>;
> + regulator-min-microvolt = <120>;
> + regulator-max-microvolt = <120>;
> + gpio = <&tlmm 9 GPIO_ACTIVE_HIGH>;
> + enable-active-high;
> + };
> +
> + lt9611_3v3: lt9611-3v3 {

Node name: drop lt9611 and add "regulator suffix

> + compatible = "regulator-fixed";
> + regulator-name = "LT9611_3V3";
> +
> + vin-supply = <&vreg_bob>;
> + gpio = <&tlmm 109 GPIO_ACTIVE_HIGH>;
> + regulator-min-microvolt = <330>;
> + regulator-max-microvolt = <330>;
> + enable-active-high;
> + };
> +
>   vph_pwr: vph-pwr-regulator {
>   compatible = "regulator-fixed";
>   regulator-name = "vph_pwr";
> @@ -349,6 +371,27 @@ vreg_l7e_2p8: ldo7 {
>   };
>  };
>  
> +&i2c9 {
> + status = "okay";
> + clock-frequency = <40>;
> +
> + lt9611_codec: hdmi-bridge@2b {
> + compatible = "lontium,lt9611uxc";
> + reg = <0x2b>;
> +
> + interrupts-extended = <&tlmm 44 IRQ_TYPE_EDGE_FALLING>;
> +
> + reset-gpios = <&tlmm 107 GPIO_ACTIVE_HIGH>;
> +
> + vdd-supply = <<9611_1v2>;
> + vcc-supply = <<9611_3v3>;
> +
> + pinctrl-names = "default";
> + pinctrl-0 = <<9611_irq_pin <9611_rst_pin>;
> +
> + };
> +};
> +
>  &pcie0 {
>   status = "okay";
>   max-link-speed = <2>;
> @@ -394,8 +437,26 @@ &qupv3_id_0 {
>   status = "okay";
>  };
>  
> +&qupv3_id_1 {
> + status = "okay";
> +};
> +
>  &tlmm {
>   gpio-reserved-ranges = <28 4>, <36 4>;
> +
> + lt9611_irq_pin: lt9611-irq {

-state


Best regards,
Krzysztof



Re: [PATCH v1 5/5] arm64: dts: qcom: sm8450-hdk: Enable HDMI Display

2022-11-04 Thread Konrad Dybcio



On 04/11/2022 14:13, Dmitry Baryshkov wrote:

From: Vinod Koul 

Add the HDMI display nodes and link it to DSI. Also enable missing dispcc
nodes

Signed-off-by: Vinod Koul 
Signed-off-by: Dmitry Baryshkov 
---
  arch/arm64/boot/dts/qcom/sm8450-hdk.dts | 45 +
  1 file changed, 45 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts 
b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
index 9522dd29a38a..f37f226e9b11 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
@@ -20,6 +20,17 @@ chosen {
stdout-path = "serial0:115200n8";
};
  
+	hdmi-out {

+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con: endpoint {
+   remote-endpoint = <<9611_out>;
+   };
+   };
+   };
+
lt9611_1v2: lt9611-vdd12-regulator {
compatible = "regulator-fixed";
regulator-name = "LT9611_1V2";
@@ -389,6 +400,26 @@ lt9611_codec: hdmi-bridge@2b {
pinctrl-names = "default";
pinctrl-0 = <<9611_irq_pin <9611_rst_pin>;
  
+		ports {

+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   lt9611_a: endpoint {
+   remote-endpoint = <&dsi0_out>;
+   };
+   };
+
+   port@2 {
+   reg = <2>;
+
+   lt9611_out: endpoint {
+   remote-endpoint = <&hdmi_con>;
+   };
+   };
+   };
};
  };
  
@@ -512,9 +543,23 @@ &mdss_mdp {

status = "okay";
  };
  
+&dispcc {

+   status = "okay";
+};


Please sort this alphabetically (though I think it's gonna be ok after 
you fix it in 3/5).



With that:


Reviewed-by: Konrad Dybcio 


Konrad


+
  &dsi0 {
status = "okay";
vdda-supply = <&vreg_l6b_1p2>;
+
+   ports {
+   port@1 {
+   endpoint {
+   remote-endpoint = <<9611_a>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+   };
+
  };
  
  &dsi0_phy {


Re: [PATCH v1 4/5] arm64: dts: qcom: sm8450-hdk: Add LT9611uxc HDMI bridge

2022-11-04 Thread Konrad Dybcio



On 04/11/2022 14:13, Dmitry Baryshkov wrote:

From: Vinod Koul 

Add the LT9611uxc DSI-HDMI bridge and supplies

Signed-off-by: Vinod Koul 
Signed-off-by: Dmitry Baryshkov 
---
  arch/arm64/boot/dts/qcom/sm8450-hdk.dts | 61 +
  1 file changed, 61 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts 
b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
index e1a4cf1ee51d..9522dd29a38a 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
@@ -20,6 +20,28 @@ chosen {
stdout-path = "serial0:115200n8";
};
  
+	lt9611_1v2: lt9611-vdd12-regulator {

+   compatible = "regulator-fixed";
+   regulator-name = "LT9611_1V2";
+
+   vin-supply = <&vph_pwr>;
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <120>;
+   gpio = <&tlmm 9 GPIO_ACTIVE_HIGH>;
+   enable-active-high;
+   };
+
+   lt9611_3v3: lt9611-3v3 {


The previous node has -regulator, this one doesn't, please keep it 
consistent.




+   compatible = "regulator-fixed";
+   regulator-name = "LT9611_3V3";
+
+   vin-supply = <&vreg_bob>;
+   gpio = <&tlmm 109 GPIO_ACTIVE_HIGH>;
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   enable-active-high;
+   };
+
vph_pwr: vph-pwr-regulator {
compatible = "regulator-fixed";
regulator-name = "vph_pwr";
@@ -349,6 +371,27 @@ vreg_l7e_2p8: ldo7 {
};
  };
  
+&i2c9 {

+   status = "okay";
+   clock-frequency = <40>;


Status last, please.


With these fixes:


Reviewed-by: Konrad Dybcio 


Konrad


+
+   lt9611_codec: hdmi-bridge@2b {
+   compatible = "lontium,lt9611uxc";
+   reg = <0x2b>;
+
+   interrupts-extended = <&tlmm 44 IRQ_TYPE_EDGE_FALLING>;
+
+   reset-gpios = <&tlmm 107 GPIO_ACTIVE_HIGH>;
+
+   vdd-supply = <<9611_1v2>;
+   vcc-supply = <<9611_3v3>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <<9611_irq_pin <9611_rst_pin>;
+
+   };
+};
+
  &pcie0 {
status = "okay";
max-link-speed = <2>;
@@ -394,8 +437,26 @@ &qupv3_id_0 {
status = "okay";
  };
  
+&qupv3_id_1 {

+   status = "okay";
+};
+
  &tlmm {
gpio-reserved-ranges = <28 4>, <36 4>;
+
+   lt9611_irq_pin: lt9611-irq {
+   pins = "gpio44";
+   function = "gpio";
+   bias-disable;
+   };
+
+   lt9611_rst_pin: lt9611-rst-state {
+   pins = "gpio107";
+   function = "normal";
+
+   output-high;
+   input-disable;
+   };
  };
  
  &uart7 {


Re: [PATCH v1 2/5] arm64: dts: qcom: sm8450: add display hardware devices

2022-11-04 Thread Krzysztof Kozlowski
On 04/11/2022 09:13, Dmitry Baryshkov wrote:
> Add devices tree nodes describing display hardware on SM8450:
> - Display Clock Controller
> - MDSS
> - MDP
> - two DSI controllers and DSI PHYs
> 
> This does not provide support for DP controllers present on SM8450.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  arch/arm64/boot/dts/qcom/sm8450.dtsi | 284 ++-
>  1 file changed, 280 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi 
> b/arch/arm64/boot/dts/qcom/sm8450.dtsi
> index 250e6b883ca3..23f989dedfdb 100644
> --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
> @@ -2401,6 +2401,282 @@ camcc: clock-controller@ade {
>   status = "disabled";
>   };
>  
> + mdss: mdss@ae0 {
> + compatible = "qcom,sm8450-mdss";
> + reg = <0 0x0ae0 0 0x1000>;
> + reg-names = "mdss";
> +
> + /* same path used twice */
> + interconnects = <&mmss_noc MASTER_MDP_DISP 0 &mc_virt 
> SLAVE_EBI1_DISP 0>,
> + <&mmss_noc MASTER_MDP_DISP 0 &mc_virt 
> SLAVE_EBI1_DISP 0>;
> + interconnect-names = "mdp0-mem", "mdp1-mem";
> +
> + resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
> +
> + power-domains = <&dispcc MDSS_GDSC>;
> +
> + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
> +  <&gcc GCC_DISP_HF_AXI_CLK>,
> +  <&gcc GCC_DISP_SF_AXI_CLK>,
> +  <&dispcc DISP_CC_MDSS_MDP_CLK>;
> + clock-names = "iface", "bus", "nrt_bus", "core";
> +
> + interrupts = ;
> + interrupt-controller;
> + #interrupt-cells = <1>;
> +
> + iommus = <&apps_smmu 0x2800 0x402>;
> +
> + status = "disabled";

Status as last property.

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


Isn't this "display-controller" in the bindings and other cases?

> + compatible = "qcom,sm8450-dpu";
> + reg = <0 0x0ae01000 0 0x8f000>,
> +   <0 0x0aeb 0 0x2008>;
> + reg-names = "mdp", "vbif";
> +
> + clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
> + <&gcc GCC_DISP_SF_AXI_CLK>,
> + <&dispcc DISP_CC_MDSS_AHB_CLK>,
> + <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
> + <&dispcc DISP_CC_MDSS_MDP_CLK>,
> + <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
> + clock-names = "bus",
> +   "nrt_bus",
> +   "iface",
> +   "lut",
> +   "core",
> +   "vsync";
> +
> + assigned-clocks = <&dispcc 
> DISP_CC_MDSS_VSYNC_CLK>;
> + assigned-clock-rates = <1920>;
> +
> + operating-points-v2 = <&mdp_opp_table>;
> + power-domains = <&rpmhpd SM8450_MMCX>;
> +
> + interrupt-parent = <&mdss>;
> + interrupts = <0>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> + dpu_intf1_out: endpoint {
> + remote-endpoint = 
> <&dsi0_in>;
> + };
> + };
> +
> + port@1 {
> + reg = <1>;
> + dpu_intf2_out: endpoint {
> + remote-endpoint = 
> <&dsi1_in>;
> + };
> + };
> +
> + };
> +
> + mdp_opp_table: mdp-opp-table {
> + compatible = "operating-points-v2";
> +
> + opp-17200 {
> + opp-hz = /bits/ 64 <17200>;
> +  

Re: [PATCH v1 3/5] arm64: dts: qcom: sm8450-hdk: enable display hardware

2022-11-04 Thread Konrad Dybcio



On 04/11/2022 14:13, Dmitry Baryshkov wrote:

Enable MDSS/DPU/DSI0 on SM8450-HDK device. Note, there is no panel
configuration (yet).

Signed-off-by: Dmitry Baryshkov 
---
  arch/arm64/boot/dts/qcom/sm8450-hdk.dts | 18 ++
  1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts 
b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
index 38ccd44620d0..e1a4cf1ee51d 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
@@ -442,3 +442,21 @@ &usb_1_qmpphy {
vdda-phy-supply = <&vreg_l6b_1p2>;
vdda-pll-supply = <&vreg_l1b_0p91>;
  };
+
+&mdss {
+   status = "okay";
+};
+
+&mdss_mdp {
+   status = "okay";
+};
+
+&dsi0 {
+   status = "okay";
+   vdda-supply = <&vreg_l6b_1p2>;
+};
+
+&dsi0_phy {
+   status = "okay";
+   vdds-supply = <&vreg_l5b_0p88>;
+};


Sort the nodes alphabetically and place status last, please.


Konrad



Re: [PATCH v1 2/5] arm64: dts: qcom: sm8450: add display hardware devices

2022-11-04 Thread Konrad Dybcio



On 04/11/2022 14:13, Dmitry Baryshkov wrote:

Add devices tree nodes describing display hardware on SM8450:
- Display Clock Controller
- MDSS
- MDP
- two DSI controllers and DSI PHYs

This does not provide support for DP controllers present on SM8450.

Signed-off-by: Dmitry Baryshkov 
---
  arch/arm64/boot/dts/qcom/sm8450.dtsi | 284 ++-
  1 file changed, 280 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi 
b/arch/arm64/boot/dts/qcom/sm8450.dtsi
index 250e6b883ca3..23f989dedfdb 100644
--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -2401,6 +2401,282 @@ camcc: clock-controller@ade {
status = "disabled";
};
  
+		mdss: mdss@ae0 {

+   compatible = "qcom,sm8450-mdss";
+   reg = <0 0x0ae0 0 0x1000>;
+   reg-names = "mdss";
+
+   /* same path used twice */
+   interconnects = <&mmss_noc MASTER_MDP_DISP 0 &mc_virt 
SLAVE_EBI1_DISP 0>,
+   <&mmss_noc MASTER_MDP_DISP 0 &mc_virt 
SLAVE_EBI1_DISP 0>;
+   interconnect-names = "mdp0-mem", "mdp1-mem";
+
+   resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
+
+   power-domains = <&dispcc MDSS_GDSC>;
+
+   clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+<&gcc GCC_DISP_HF_AXI_CLK>,
+<&gcc GCC_DISP_SF_AXI_CLK>,
+<&dispcc DISP_CC_MDSS_MDP_CLK>;
+   clock-names = "iface", "bus", "nrt_bus", "core";
+
+   interrupts = ;
+   interrupt-controller;
+   #interrupt-cells = <1>;
+
+   iommus = <&apps_smmu 0x2800 0x402>;
+
+   status = "disabled";
+
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+
+   mdss_mdp: mdp@ae01000 {
+   compatible = "qcom,sm8450-dpu";
+   reg = <0 0x0ae01000 0 0x8f000>,
+ <0 0x0aeb 0 0x2008>;
+   reg-names = "mdp", "vbif";
+
+   clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
+   <&gcc GCC_DISP_SF_AXI_CLK>,
+   <&dispcc DISP_CC_MDSS_AHB_CLK>,
+   <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
+   <&dispcc DISP_CC_MDSS_MDP_CLK>,
+   <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
+   clock-names = "bus",
+ "nrt_bus",
+ "iface",
+ "lut",
+ "core",
+ "vsync";
+
+   assigned-clocks = <&dispcc 
DISP_CC_MDSS_VSYNC_CLK>;
+   assigned-clock-rates = <1920>;
+
+   operating-points-v2 = <&mdp_opp_table>;
+   power-domains = <&rpmhpd SM8450_MMCX>;
+
+   interrupt-parent = <&mdss>;
+   interrupts = <0>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+   dpu_intf1_out: endpoint {
+   remote-endpoint = 
<&dsi0_in>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   dpu_intf2_out: endpoint {
+   remote-endpoint = 
<&dsi1_in>;
+   };
+   };
+
+   };
+
+   mdp_opp_table: mdp-opp-table {
+   compatible = "operating-points-v2";
+
+   opp-17200 {
+   opp-hz = /bits/ 64 <17200>;
+   required-opps = 
<&rpmhpd_opp_low_svs_d1>;
+   };
+
+   opp-2 {
+

[PATCH v3 04/12] drm/mediatek: extract common functions from the mtk hdmi driver

2022-11-04 Thread Guillaume Ranquet
Create a common "framework" that can be used to add support for
different hdmi IPs within the mediatek range of products.

Signed-off-by: Guillaume Ranquet 
---
 drivers/gpu/drm/mediatek/Makefile  |   3 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c| 620 ++---
 drivers/gpu/drm/mediatek/mtk_hdmi.h|  16 +
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 433 
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h | 221 ++
 5 files changed, 704 insertions(+), 589 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index d4d193f60271..79bbaa58893e 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -22,7 +22,8 @@ obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
 mediatek-drm-hdmi-objs := mtk_cec.o \
  mtk_hdmi.o \
- mtk_hdmi_ddc.o
+ mtk_hdmi_common.o \
+ mtk_hdmi_ddc.o \
 
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 9b02b30a193a..73bda2849196 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -31,187 +31,18 @@
 #include 
 
 #include "mtk_cec.h"
-#include "mtk_hdmi.h"
 #include "mtk_hdmi_regs.h"
+#include "mtk_hdmi_common.h"
 
 #define NCTS_BYTES 7
 
-enum mtk_hdmi_clk_id {
-   MTK_HDMI_CLK_HDMI_PIXEL,
-   MTK_HDMI_CLK_HDMI_PLL,
-   MTK_HDMI_CLK_AUD_BCLK,
-   MTK_HDMI_CLK_AUD_SPDIF,
-   MTK_HDMI_CLK_COUNT
+const char * const mtk_hdmi_clk_names_v1[MTK_HDMIV1_CLK_COUNT] = {
+   [MTK_HDMIV1_CLK_HDMI_PIXEL] = "pixel",
+   [MTK_HDMIV1_CLK_HDMI_PLL] = "pll",
+   [MTK_HDMIV1_CLK_AUD_BCLK] = "bclk",
+   [MTK_HDMIV1_CLK_AUD_SPDIF] = "spdif",
 };
 
-enum hdmi_aud_input_type {
-   HDMI_AUD_INPUT_I2S = 0,
-   HDMI_AUD_INPUT_SPDIF,
-};
-
-enum hdmi_aud_i2s_fmt {
-   HDMI_I2S_MODE_RJT_24BIT = 0,
-   HDMI_I2S_MODE_RJT_16BIT,
-   HDMI_I2S_MODE_LJT_24BIT,
-   HDMI_I2S_MODE_LJT_16BIT,
-   HDMI_I2S_MODE_I2S_24BIT,
-   HDMI_I2S_MODE_I2S_16BIT
-};
-
-enum hdmi_aud_mclk {
-   HDMI_AUD_MCLK_128FS,
-   HDMI_AUD_MCLK_192FS,
-   HDMI_AUD_MCLK_256FS,
-   HDMI_AUD_MCLK_384FS,
-   HDMI_AUD_MCLK_512FS,
-   HDMI_AUD_MCLK_768FS,
-   HDMI_AUD_MCLK_1152FS,
-};
-
-enum hdmi_aud_channel_type {
-   HDMI_AUD_CHAN_TYPE_1_0 = 0,
-   HDMI_AUD_CHAN_TYPE_1_1,
-   HDMI_AUD_CHAN_TYPE_2_0,
-   HDMI_AUD_CHAN_TYPE_2_1,
-   HDMI_AUD_CHAN_TYPE_3_0,
-   HDMI_AUD_CHAN_TYPE_3_1,
-   HDMI_AUD_CHAN_TYPE_4_0,
-   HDMI_AUD_CHAN_TYPE_4_1,
-   HDMI_AUD_CHAN_TYPE_5_0,
-   HDMI_AUD_CHAN_TYPE_5_1,
-   HDMI_AUD_CHAN_TYPE_6_0,
-   HDMI_AUD_CHAN_TYPE_6_1,
-   HDMI_AUD_CHAN_TYPE_7_0,
-   HDMI_AUD_CHAN_TYPE_7_1,
-   HDMI_AUD_CHAN_TYPE_3_0_LRS,
-   HDMI_AUD_CHAN_TYPE_3_1_LRS,
-   HDMI_AUD_CHAN_TYPE_4_0_CLRS,
-   HDMI_AUD_CHAN_TYPE_4_1_CLRS,
-   HDMI_AUD_CHAN_TYPE_6_1_CS,
-   HDMI_AUD_CHAN_TYPE_6_1_CH,
-   HDMI_AUD_CHAN_TYPE_6_1_OH,
-   HDMI_AUD_CHAN_TYPE_6_1_CHR,
-   HDMI_AUD_CHAN_TYPE_7_1_LH_RH,
-   HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR,
-   HDMI_AUD_CHAN_TYPE_7_1_LC_RC,
-   HDMI_AUD_CHAN_TYPE_7_1_LW_RW,
-   HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD,
-   HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS,
-   HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS,
-   HDMI_AUD_CHAN_TYPE_7_1_CS_CH,
-   HDMI_AUD_CHAN_TYPE_7_1_CS_OH,
-   HDMI_AUD_CHAN_TYPE_7_1_CS_CHR,
-   HDMI_AUD_CHAN_TYPE_7_1_CH_OH,
-   HDMI_AUD_CHAN_TYPE_7_1_CH_CHR,
-   HDMI_AUD_CHAN_TYPE_7_1_OH_CHR,
-   HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR,
-   HDMI_AUD_CHAN_TYPE_6_0_CS,
-   HDMI_AUD_CHAN_TYPE_6_0_CH,
-   HDMI_AUD_CHAN_TYPE_6_0_OH,
-   HDMI_AUD_CHAN_TYPE_6_0_CHR,
-   HDMI_AUD_CHAN_TYPE_7_0_LH_RH,
-   HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR,
-   HDMI_AUD_CHAN_TYPE_7_0_LC_RC,
-   HDMI_AUD_CHAN_TYPE_7_0_LW_RW,
-   HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD,
-   HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS,
-   HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS,
-   HDMI_AUD_CHAN_TYPE_7_0_CS_CH,
-   HDMI_AUD_CHAN_TYPE_7_0_CS_OH,
-   HDMI_AUD_CHAN_TYPE_7_0_CS_CHR,
-   HDMI_AUD_CHAN_TYPE_7_0_CH_OH,
-   HDMI_AUD_CHAN_TYPE_7_0_CH_CHR,
-   HDMI_AUD_CHAN_TYPE_7_0_OH_CHR,
-   HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR,
-   HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS,
-   HDMI_AUD_CHAN_TYPE_UNKNOWN = 0xFF
-};
-
-enum hdmi_aud_channel_swap_type {
-   HDMI_AUD_SWAP_LR,
-   HDMI_AUD_SWAP_LFE_CC,
-   HDMI_AUD_SWAP_LSRS,
-   HDMI_AUD_SWAP_RLS_RRS,
-   HDMI_AUD_SWAP_LR_STATUS,
-};
-
-struct hdmi_audio_param {
-   enum hdmi_audio_coding_type aud_codec;
-   enum hdmi_audio_sample_size aud_sampe_size;
-   enum hdmi_aud_input_type aud_input_type;
-   enum hdmi_aud_i2s_fmt aud_i2s_fmt;
-   enum hdmi_aud_mclk aud_mclk;
-   e

[PATCH v3 11/12] dt-bindings: display: mediatek: dpi: Add compatible for MediaTek MT8195

2022-11-04 Thread Guillaume Ranquet
Add dt-binding documentation of dpi for MediaTek MT8195 SoC.

Acked-by: Krzysztof Kozlowski 
Signed-off-by: Guillaume Ranquet 
---
 Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
index 5bb23e97cf33..2c7ecef54986 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
@@ -24,6 +24,7 @@ properties:
   - mediatek,mt8183-dpi
   - mediatek,mt8186-dpi
   - mediatek,mt8192-dpi
+  - mediatek,mt8195-dpi
   - mediatek,mt8195-dp-intf
 
   reg:

-- 
b4 0.11.0-dev


[PATCH v3 10/12] phy: mediatek: add support for phy-mtk-hdmi-mt8195

2022-11-04 Thread Guillaume Ranquet
Add basic support for the mediatek hdmi phy on MT8195 SoC

Signed-off-by: Guillaume Ranquet 
---
 drivers/phy/mediatek/Makefile  |   1 +
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 543 +
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h | 109 ++
 drivers/phy/mediatek/phy-mtk-hdmi.c|   3 +
 drivers/phy/mediatek/phy-mtk-hdmi.h|   1 +
 5 files changed, 657 insertions(+)

diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index fb1f8edaffa7..c9a50395533e 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PHY_MTK_XSPHY)   += phy-mtk-xsphy.o
 phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o
 phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o
 phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt8173.o
+phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt8195.o
 obj-$(CONFIG_PHY_MTK_HDMI) += phy-mtk-hdmi-drv.o
 
 phy-mtk-mipi-dsi-drv-y := phy-mtk-mipi-dsi.o
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c 
b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
new file mode 100644
index ..48efd3936f29
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
@@ -0,0 +1,543 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre, SAS
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "phy-mtk-io.h"
+#include "phy-mtk-hdmi.h"
+#include "phy-mtk-hdmi-mt8195.h"
+
+static void mtk_hdmi_ana_fifo_en(struct mtk_hdmi_phy *hdmi_phy)
+{
+   /* make data fifo writable for hdmi2.0 */
+   mtk_phy_set_bits(hdmi_phy->regs + HDMI_ANA_CTL, REG_ANA_HDMI20_FIFO_EN);
+}
+
+static void
+mtk_mt8195_phy_tmds_high_bit_clk_ratio(struct mtk_hdmi_phy *hdmi_phy,
+  bool enable)
+{
+   void __iomem *regs = hdmi_phy->regs;
+
+   mtk_hdmi_ana_fifo_en(hdmi_phy);
+
+   /* HDMI 2.0 specification, 3.4Gbps <= TMDS Bit Rate <= 6G,
+* clock bit ratio 1:40, under 3.4Gbps, clock bit ratio 1:10
+*/
+   if (enable)
+   mtk_phy_update_field(regs + HDMI20_CLK_CFG, REG_TXC_DIV, 
REG_TXC_DIV);
+   else
+   mtk_phy_clear_bits(regs + HDMI20_CLK_CFG, REG_TXC_DIV);
+}
+
+static void mtk_hdmi_pll_select_source(struct clk_hw *hw)
+{
+   struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+   void __iomem *regs = hdmi_phy->regs;
+
+   mtk_phy_clear_bits(regs + HDMI_CTL_3, REG_HDMITX_REF_XTAL_SEL);
+   mtk_phy_clear_bits(regs + HDMI_CTL_3, REG_HDMITX_REF_RESPLL_SEL);
+
+   /* DA_HDMITX21_REF_CK for TXPLL input source */
+   mtk_phy_clear_bits(regs + HDMI_1_CFG_10, RG_HDMITXPLL_REF_CK_SEL);
+}
+
+static int mtk_hdmi_pll_performance_setting(struct clk_hw *hw)
+{
+   struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+   void __iomem *regs = hdmi_phy->regs;
+
+   /* BP2 */
+   mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_0, RG_HDMITXPLL_BP2);
+
+   /* BC */
+   mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_BC);
+
+   /* IC */
+   mtk_phy_update_field(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_IC, 0x1);
+
+   /* BR */
+   mtk_phy_update_field(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_BR, 0x2);
+
+   /* IR */
+   mtk_phy_update_field(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_IR, 0x2);
+
+   /* BP */
+   mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_BP);
+
+   /* IBAND_FIX_EN, RESERVE[14] */
+   mtk_phy_clear_bits(regs + HDMI_1_PLL_CFG_0, RG_HDMITXPLL_IBAND_FIX_EN);
+   mtk_phy_clear_bits(regs + HDMI_1_PLL_CFG_1, RG_HDMITXPLL_RESERVE_BIT14);
+
+   /* HIKVCO */
+   mtk_phy_clear_bits(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_HIKVCO);
+
+   /* HREN */
+   mtk_phy_update_field(regs + HDMI_1_PLL_CFG_0, RG_HDMITXPLL_HREN, 0x1);
+
+   /* LVR_SEL */
+   mtk_phy_update_field(regs + HDMI_1_PLL_CFG_0, RG_HDMITXPLL_LVR_SEL, 
0x1);
+
+   /* RG_HDMITXPLL_RESERVE[12:11] */
+   mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_1, 
RG_HDMITXPLL_RESERVE_BIT12_11);
+
+   /* TCL_EN */
+   mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_0, RG_HDMITXPLL_TCL_EN);
+
+   return 0;
+}
+
+static int mtk_hdmi_pll_set_hw(struct clk_hw *hw, unsigned char prediv,
+  unsigned char fbkdiv_high,
+  unsigned long fbkdiv_low,
+  unsigned char fbkdiv_hs3, unsigned char posdiv1,
+  unsigned char posdiv2, unsigned char txprediv,
+  unsigned char txposdiv,
+  unsigned char digital_div)
+{
+   unsigned char txposdiv_value = 0;
+   unsigned char div3_ctrl_value = 0;
+   unsigned char posdiv_vallue = 0;
+   unsigned char div_ctrl_value = 0;
+   unsigned char reserve_3_2_value = 0;
+   uns

[PATCH v3 08/12] drm/mediatek: hdmi: v2: add audio support

2022-11-04 Thread Guillaume Ranquet
Add HDMI audio support for v2

Signed-off-by: Guillaume Ranquet 
---
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c |   1 +
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c |   2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c | 213 +
 drivers/gpu/drm/mediatek/mtk_hdmi_v2.h |   2 +
 4 files changed, 217 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index e43c938a9aa5..1ea91f8bb6c7 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -386,6 +386,7 @@ static const struct mtk_hdmi_conf mtk_hdmi_conf_v2 = {
.mtk_hdmi_output_init = mtk_hdmi_output_init_v2,
.mtk_hdmi_clk_disable = mtk_hdmi_clk_disable_v2,
.mtk_hdmi_clk_enable = mtk_hdmi_clk_enable_v2,
+   .set_hdmi_codec_pdata = set_hdmi_codec_pdata_v2,
.mtk_hdmi_clock_names = mtk_hdmi_clk_names_v2,
.num_clocks = MTK_HDMIV2_CLK_COUNT,
 };
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
index 61696d255e51..26456802a5c4 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
@@ -309,7 +309,7 @@ static int mtk_hdmi_ddc_probe(struct platform_device *pdev)
ddc->regs = device_node_to_regmap(hdmi);
of_node_put(hdmi);
if (IS_ERR(ddc->regs))
-   return dev_err_probe(dev, PTR_ERR(ddc->regs), "Unable to get 
mt8195-hdmi syscon");
+   return dev_err_probe(dev, PTR_ERR(ddc->regs), "Unable to get 
hdmi syscon");
 
ddc->clk = devm_clk_get_enabled(dev, "ddc");
if (IS_ERR(ddc->clk))
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
index e8457429964d..b391b22fa9f5 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
@@ -211,6 +211,26 @@ static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, 
bool black)
mtk_hdmi_mask(hdmi, TOP_VMUTE_CFG1, 0, REG_VMUTE_EN);
 }
 
+static void mtk_hdmi_hw_aud_mute(struct mtk_hdmi *hdmi)
+{
+   u32 val;
+
+   val = mtk_hdmi_read(hdmi, AIP_CTRL, &val);
+
+   if (val & DSD_EN)
+   mtk_hdmi_mask(hdmi, AIP_TXCTRL,
+ DSD_MUTE_DATA | AUD_MUTE_FIFO_EN,
+ DSD_MUTE_DATA | AUD_MUTE_FIFO_EN);
+   else
+   mtk_hdmi_mask(hdmi, AIP_TXCTRL, AUD_MUTE_FIFO_EN,
+ AUD_MUTE_FIFO_EN);
+}
+
+static void mtk_hdmi_hw_aud_unmute(struct mtk_hdmi *hdmi)
+{
+   mtk_hdmi_mask(hdmi, AIP_TXCTRL, AUD_MUTE_DIS, AUD_MUTE_FIFO_EN);
+}
+
 static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi)
 {
mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0x0, HDMITX_SW_RSTB);
@@ -889,6 +909,7 @@ static void mtk_hdmi_audio_reset(struct mtk_hdmi *hdmi, 
bool rst)
 static void mtk_hdmi_aud_output_config(struct mtk_hdmi *hdmi,
   struct drm_display_mode *display_mode)
 {
+   mtk_hdmi_hw_aud_mute(hdmi);
mtk_hdmi_aud_enable_packet(hdmi, false);
mtk_hdmi_audio_reset(hdmi, true);
mtk_hdmi_aip_ctrl_init(hdmi);
@@ -901,6 +922,7 @@ static void mtk_hdmi_aud_output_config(struct mtk_hdmi 
*hdmi,
usleep_range(25, 50);
mtk_hdmi_aud_on_off_hw_ncts(hdmi, true);
mtk_hdmi_aud_enable_packet(hdmi, true);
+   mtk_hdmi_hw_aud_unmute(hdmi);
 }
 
 void mtk_hdmi_output_init_v2(struct mtk_hdmi *hdmi)
@@ -935,6 +957,28 @@ static void mtk_hdmi_reset_colorspace_setting(struct 
mtk_hdmi *hdmi)
hdmi->ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
 }
 
+static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)
+{
+   mtk_hdmi_aud_enable_packet(hdmi, true);
+   hdmi->audio_enable = true;
+}
+
+static void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi)
+{
+   mtk_hdmi_aud_enable_packet(hdmi, false);
+   hdmi->audio_enable = false;
+}
+
+static void mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi,
+struct hdmi_audio_param *param)
+{
+   if (!hdmi->audio_enable)
+   return;
+
+   memcpy(&hdmi->aud_param, param, sizeof(*param));
+   mtk_hdmi_aud_output_config(hdmi, &hdmi->mode);
+}
+
 static void mtk_hdmi_change_video_resolution(struct mtk_hdmi *hdmi)
 {
bool is_over_340M = false;
@@ -955,6 +999,7 @@ static void mtk_hdmi_change_video_resolution(struct 
mtk_hdmi *hdmi)
 
usleep_range(5, 10);
mtk_hdmi_hw_vid_black(hdmi, true);
+   mtk_hdmi_hw_aud_mute(hdmi);
mtk_hdmi_hw_send_av_unmute(hdmi);
 
mtk_hdmi_mask(hdmi, TOP_CFG01, NULL_PKT_VSYNC_HIGH_EN,
@@ -1285,6 +1330,7 @@ static void mtk_hdmi_bridge_disable(struct drm_bridge 
*bridge,
mtk_hdmi_hw_send_av_mute(hdmi);
usleep_range(5, 50050);
mtk_hdmi_hw_vid_black(hdmi, true);
+   mtk_hdmi_hw_aud_mute(hdmi);
mtk_hdmi_disable_hdcp_encr

[PATCH v3 12/12] drm/mediatek: dpi: Add mt8195 hdmi to DPI driver

2022-11-04 Thread Guillaume Ranquet
Add the DPI1 hdmi path support in mtk dpi driver

Signed-off-by: Guillaume Ranquet 
---
 drivers/gpu/drm/mediatek/mtk_dpi.c  | 143 ++--
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |   5 ++
 2 files changed, 141 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 508a6d994e83..8052b47042b8 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -14,7 +14,10 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
+#include 
 
 #include 
 
@@ -65,10 +68,14 @@ struct mtk_dpi {
struct drm_bridge *next_bridge;
struct drm_connector *connector;
void __iomem *regs;
+   struct reset_control *reset_ctl;
struct device *dev;
struct clk *engine_clk;
+   struct clk *dpi_ck_cg;
struct clk *pixel_clk;
+   struct clk *dpi_sel_clk;
struct clk *tvd_clk;
+   struct clk *hdmi_cg;
int irq;
struct drm_display_mode mode;
const struct mtk_dpi_conf *conf;
@@ -134,6 +141,7 @@ struct mtk_dpi_yc_limit {
  * @yuv422_en_bit: Enable bit of yuv422.
  * @csc_enable_bit: Enable bit of CSC.
  * @pixels_per_iter: Quantity of transferred pixels per iteration.
+ * @is_internal_hdmi: True if this DPI block is directly connected to SoC 
internal HDMI block
  */
 struct mtk_dpi_conf {
unsigned int (*cal_factor)(int clock);
@@ -152,6 +160,7 @@ struct mtk_dpi_conf {
u32 yuv422_en_bit;
u32 csc_enable_bit;
u32 pixels_per_iter;
+   bool is_internal_hdmi;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -465,8 +474,15 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
 
mtk_dpi_disable(dpi);
+
+   reset_control_rearm(dpi->reset_ctl);
+
clk_disable_unprepare(dpi->pixel_clk);
clk_disable_unprepare(dpi->engine_clk);
+   clk_disable_unprepare(dpi->dpi_sel_clk);
+   clk_disable_unprepare(dpi->dpi_ck_cg);
+   clk_disable_unprepare(dpi->hdmi_cg);
+   clk_disable_unprepare(dpi->tvd_clk);
 }
 
 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
@@ -482,12 +498,44 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
goto err_refcount;
}
 
+   ret = clk_prepare_enable(dpi->dpi_sel_clk);
+   if (ret) {
+   dev_err(dpi->dev, "failed to enable dpi_sel clock: %d\n", ret);
+   goto err_refcount;
+   }
+
+   ret = clk_prepare_enable(dpi->tvd_clk);
+   if (ret) {
+   dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
+   goto err_tvd;
+   }
+
+   ret = clk_prepare_enable(dpi->engine_clk);
+   if (ret) {
+   dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
+   goto err_engine;
+   }
+
+   ret = clk_prepare_enable(dpi->hdmi_cg);
+   if (ret) {
+   dev_err(dpi->dev, "Failed to enable hdmi_cg clock: %d\n", ret);
+   goto err_hdmi_cg;
+   }
+
+   ret = clk_prepare_enable(dpi->dpi_ck_cg);
+   if (ret) {
+   dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", 
ret);
+   goto err_ck_cg;
+   }
+
ret = clk_prepare_enable(dpi->pixel_clk);
if (ret) {
dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
goto err_pixel;
}
 
+   reset_control_reset(dpi->reset_ctl);
+
if (dpi->pinctrl && dpi->pins_dpi)
pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
 
@@ -495,6 +543,15 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 
 err_pixel:
clk_disable_unprepare(dpi->engine_clk);
+   clk_disable_unprepare(dpi->dpi_ck_cg);
+err_ck_cg:
+   clk_disable_unprepare(dpi->hdmi_cg);
+err_hdmi_cg:
+   clk_disable_unprepare(dpi->engine_clk);
+err_engine:
+   clk_disable_unprepare(dpi->tvd_clk);
+err_tvd:
+   clk_disable_unprepare(dpi->dpi_sel_clk);
 err_refcount:
dpi->refcount--;
return ret;
@@ -538,7 +595,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
else
clk_set_rate(dpi->pixel_clk, vm.pixelclock);
 
-
vm.pixelclock = clk_get_rate(dpi->pixel_clk);
 
dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
@@ -605,7 +661,16 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
if (dpi->conf->support_direct_pin) {
mtk_dpi_config_yc_map(dpi, dpi->yc_map);
mtk_dpi_config_2n_h_fre(dpi);
-   mtk_dpi_dual_edge(dpi);
+   /* DPI could be connecting to external bridge
+* or internal HDMI encoder. */
+   if (dpi->conf->is_internal_hdmi) {
+   mtk_dpi_mask(dpi, DPI_CON, DPI_OUTPUT_1T1P_EN,
+DPI_OUTPUT_1T1P_EN);
+  

[PATCH v3 09/12] phy: phy-mtk-hdmi: Add generic phy configure callback

2022-11-04 Thread Guillaume Ranquet
Some phys, such as mt8195, needs to have a configure callback defined.

Reviewed-by: AngeloGioacchino Del Regno 

Signed-off-by: Guillaume Ranquet 
---
 drivers/phy/mediatek/phy-mtk-hdmi.c | 12 
 drivers/phy/mediatek/phy-mtk-hdmi.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c 
b/drivers/phy/mediatek/phy-mtk-hdmi.c
index b16d437d6721..32f713301768 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -8,10 +8,12 @@
 
 static int mtk_hdmi_phy_power_on(struct phy *phy);
 static int mtk_hdmi_phy_power_off(struct phy *phy);
+static int mtk_hdmi_phy_configure(struct phy *phy, union phy_configure_opts 
*opts);
 
 static const struct phy_ops mtk_hdmi_phy_dev_ops = {
.power_on = mtk_hdmi_phy_power_on,
.power_off = mtk_hdmi_phy_power_off,
+   .configure = mtk_hdmi_phy_configure,
.owner = THIS_MODULE,
 };
 
@@ -43,6 +45,16 @@ static int mtk_hdmi_phy_power_off(struct phy *phy)
return 0;
 }
 
+static int mtk_hdmi_phy_configure(struct phy *phy, union phy_configure_opts 
*opts)
+{
+   struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy);
+
+   if (hdmi_phy->conf->hdmi_phy_configure)
+   return hdmi_phy->conf->hdmi_phy_configure(phy, opts);
+
+   return 0;
+}
+
 static const struct phy_ops *
 mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy)
 {
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h 
b/drivers/phy/mediatek/phy-mtk-hdmi.h
index c7fa65cff989..f5aac9d352d8 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.h
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.h
@@ -24,6 +24,7 @@ struct mtk_hdmi_phy_conf {
const struct clk_ops *hdmi_phy_clk_ops;
void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
+   int (*hdmi_phy_configure)(struct phy *phy, union phy_configure_opts 
*opts);
 };
 
 struct mtk_hdmi_phy {

-- 
b4 0.11.0-dev


[PATCH v3 06/12] drm/mediatek: hdmi: add frame_colorimetry flag

2022-11-04 Thread Guillaume Ranquet
Add a flag to indicate support for frame colorimetry.

Signed-off-by: Guillaume Ranquet 
---
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 11 +++
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index 3635ca66817b..933c51b5f6d7 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -120,6 +120,17 @@ int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi, u8 
*buffer, size_t bufsz
return err;
}
 
+   if (hdmi->conf->has_frame_colorimetry) {
+   frame.colorimetry = hdmi->colorimtery;
+   if (frame.colorimetry == HDMI_COLORIMETRY_EXTENDED)
+   frame.extended_colorimetry = hdmi->extended_colorimetry;
+
+   /* quantiation range:limited or full */
+   if (frame.colorspace == HDMI_COLORSPACE_RGB)
+   frame.quantization_range = hdmi->quantization_range;
+   else
+   frame.ycc_quantization_range = 
hdmi->ycc_quantization_range;
+   }
err = hdmi_avi_infoframe_pack(&frame, buffer, bufsz);
 
if (err < 0) {
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h 
b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
index 921bde150e11..2e8e5feec377 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
@@ -32,6 +32,7 @@ struct mtk_hdmi_conf {
bool tz_disabled;
bool cea_modes_only;
bool has_cec;
+   bool has_frame_colorimetry;
unsigned long max_mode_clock;
const struct drm_bridge_funcs *bridge_funcs;
void (*mtk_hdmi_output_init)(struct mtk_hdmi *hdmi);

-- 
b4 0.11.0-dev


[PATCH v3 07/12] drm/mediatek: hdmi: add v2 support

2022-11-04 Thread Guillaume Ranquet
Adds hdmi and hdmi-ddc support for v2 IP.

Signed-off-by: Guillaume Ranquet 
---
 drivers/gpu/drm/mediatek/Makefile   |2 +
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c  |   14 +
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h  |1 +
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c  |  367 +++
 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h |  309 ++
 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c  | 1379 +++
 drivers/gpu/drm/mediatek/mtk_hdmi_v2.h  |   29 +
 7 files changed, 2101 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index 79bbaa58893e..bb60856b629e 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -24,6 +24,8 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
  mtk_hdmi.o \
  mtk_hdmi_common.o \
  mtk_hdmi_ddc.o \
+ mtk_hdmi_ddc_v2.o \
+ mtk_hdmi_v2.o \
 
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index 933c51b5f6d7..e43c938a9aa5 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -380,6 +380,16 @@ static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8173 = {
.num_clocks = MTK_HDMIV1_CLK_COUNT,
 };
 
+static const struct mtk_hdmi_conf mtk_hdmi_conf_v2 = {
+   .has_frame_colorimetry = true,
+   .bridge_funcs = &mtk_v2_hdmi_bridge_funcs,
+   .mtk_hdmi_output_init = mtk_hdmi_output_init_v2,
+   .mtk_hdmi_clk_disable = mtk_hdmi_clk_disable_v2,
+   .mtk_hdmi_clk_enable = mtk_hdmi_clk_enable_v2,
+   .mtk_hdmi_clock_names = mtk_hdmi_clk_names_v2,
+   .num_clocks = MTK_HDMIV2_CLK_COUNT,
+};
+
 static const struct of_device_id mtk_drm_hdmi_of_ids[] = {
{ .compatible = "mediatek,mt2701-hdmi",
  .data = &mtk_hdmi_conf_mt2701,
@@ -390,6 +400,9 @@ static const struct of_device_id mtk_drm_hdmi_of_ids[] = {
{ .compatible = "mediatek,mt8173-hdmi",
  .data = &mtk_hdmi_conf_mt8173,
},
+   { .compatible = "mediatek,mt8195-hdmi",
+ .data = &mtk_hdmi_conf_v2,
+   },
{}
 };
 MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_of_ids);
@@ -438,6 +451,7 @@ static struct platform_driver mtk_hdmi_driver = {
 static struct platform_driver * const mtk_hdmi_drivers[] = {
&mtk_hdmi_ddc_driver,
&mtk_cec_driver,
+   &mtk_hdmi_ddc_v2_driver,
&mtk_hdmi_driver,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h 
b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
index 2e8e5feec377..d030b71b5231 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
@@ -27,6 +27,7 @@
 
 #include "mtk_cec.h"
 #include "mtk_hdmi.h"
+#include "mtk_hdmi_v2.h"
 
 struct mtk_hdmi_conf {
bool tz_disabled;
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
new file mode 100644
index ..61696d255e51
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Copyright (c) 2021 BayLibre, SAS
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "mtk_hdmi_regs_v2.h"
+#include "mtk_hdmi_v2.h"
+
+#define EDID_ID 0x50
+#define DDC2_CLOK 572 /* BIM=208M/(v*4) = 90Khz */
+#define DDC2_CLOK_EDID 832 /* BIM=208M/(v*4) = 62.5Khz */
+
+struct mtk_hdmi_ddc {
+   struct device *dev;
+   /* Serialize read/write operations */
+   struct mutex mtx;
+   struct i2c_adapter adap;
+   struct clk *clk;
+   void __iomem *regs;
+};
+
+enum sif_bit_t_hdmi {
+   SIF_8_BIT_HDMI, /* /< [8 bits data address.] */
+   SIF_16_BIT_HDMI, /* /< [16 bits data address.] */
+};
+
+static void hdmi_ddc_request(struct mtk_hdmi_ddc *ddc)
+{
+   regmap_update_bits(ddc->regs, HDCP2X_POL_CTRL, HDCP2X_DIS_POLL_EN,
+HDCP2X_DIS_POLL_EN);
+}
+
+static void mtk_ddc_wr_one(struct mtk_hdmi_ddc *ddc, unsigned int addr_id,
+  unsigned int offset_id, unsigned char wr_data)
+{
+   u32 val;
+
+   regmap_read(ddc->regs, HDCP2X_DDCM_STATUS, &val);
+
+   if (val & DDC_I2C_BUS_LOW) {
+   regmap_update_bits(ddc->regs, DDC_CTRL, FIELD_PREP(DDC_CMD, 
CLOCK_SCL), DDC_CMD);
+   usleep_range(250, 300);
+   }
+   regmap_update_bits(ddc->regs, HPD_DDC_CTRL, FIELD_PREP(DDC_DELAY_CNT, 
DDC2_CLOK), DDC_DELAY_CNT);
+   regmap_write(ddc->regs, SI2C_CTRL, FIELD_PREP(SI2C_ADDR, 
SI2C_ADDR_READ));
+   regmap_update_bits(ddc->regs, SI2C_CTRL, FIELD_PREP(SI2C_WDATA, 
wr_data), SI2C_WDATA);
+

[PATCH v3 05/12] drm/mediatek: hdmi: make the cec dev optional

2022-11-04 Thread Guillaume Ranquet
Make cec device optional in order to support newer versions of the
hdmi IP which doesn't require it

Signed-off-by: Guillaume Ranquet 
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c|  8 +++--
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 54 --
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h |  1 +
 3 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 73bda2849196..85c6ebca36dd 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -927,10 +927,11 @@ void mtk_hdmi_clk_disable_audio_mt8183(struct mtk_hdmi 
*hdmi)
 static enum drm_connector_status
 mtk_hdmi_update_plugged_status(struct mtk_hdmi *hdmi)
 {
-   bool connected;
+   bool connected = true;
 
mutex_lock(&hdmi->update_plugged_status_lock);
-   connected = mtk_cec_hpd_high(hdmi->cec_dev);
+   if (hdmi->cec_dev)
+   connected = mtk_cec_hpd_high(hdmi->cec_dev);
if (hdmi->plugged_cb && hdmi->codec_dev)
hdmi->plugged_cb(hdmi->codec_dev, connected);
mutex_unlock(&hdmi->update_plugged_status_lock);
@@ -1025,7 +1026,8 @@ static int mtk_hdmi_bridge_attach(struct drm_bridge 
*bridge,
return ret;
}
 
-   mtk_cec_set_hpd_event(hdmi->cec_dev, mtk_hdmi_hpd_event, hdmi->dev);
+   if (hdmi->cec_dev)
+   mtk_cec_set_hpd_event(hdmi->cec_dev, mtk_hdmi_hpd_event, 
hdmi->dev);
 
return 0;
 }
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index 3f08d37b1af0..3635ca66817b 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -137,28 +137,18 @@ void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, u8 
*buffer_spd, size_t bufsz
mtk_hdmi_setup_spd_infoframe(hdmi, buffer_spd, bufsz_spd, "mediatek", 
"On-chip HDMI");
 }
 
-int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device 
*pdev,
-   const char *const *clk_names, size_t num_clocks)
+static int mtk_hdmi_get_cec_dev(struct mtk_hdmi *hdmi, struct device *dev, 
struct device_node *np)
 {
-   struct device *dev = &pdev->dev;
-   struct device_node *np = dev->of_node;
-   struct device_node *cec_np, *remote, *i2c_np;
+   int ret;
+   struct device_node *cec_np;
struct platform_device *cec_pdev;
struct regmap *regmap;
-   struct resource *mem;
-   int ret;
-
-   ret = mtk_hdmi_get_all_clk(hdmi, np, clk_names, num_clocks);
-   if (ret) {
-   dev_err(dev, "Failed to get all clks\n");
-   return ret;
-   }
 
/* The CEC module handles HDMI hotplug detection */
cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");
if (!cec_np) {
dev_err(dev, "Failed to find CEC node\n");
-   return -EINVAL;
+   return -ENOTSUPP;
}
 
cec_pdev = of_find_device_by_node(cec_np);
@@ -168,7 +158,6 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct 
platform_device *pdev,
return -EPROBE_DEFER;
}
of_node_put(cec_np);
-   hdmi->cec_dev = &cec_pdev->dev;
/*
 * The mediatek,syscon-hdmi property contains a phandle link to the
 * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG
@@ -177,12 +166,41 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct 
platform_device *pdev,
regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi");
ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, 
&hdmi->sys_offset);
if (IS_ERR(regmap))
-   ret = PTR_ERR(regmap);
+   return PTR_ERR(regmap);
if (ret) {
-   dev_err(dev, "Failed to get system configuration registers: 
%d\n", ret);
-   goto put_device;
+   dev_err(dev,
+   "Failed to get system configuration registers: 
%d\n", ret);
+   return ret;
}
+
hdmi->sys_regmap = regmap;
+   hdmi->cec_dev = &cec_pdev->dev;
+
+   return 0;
+}
+
+int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device 
*pdev,
+   const char *const *clk_names, size_t num_clocks)
+{
+   struct device *dev = &pdev->dev;
+   struct device_node *np = dev->of_node;
+   struct device_node *remote, *i2c_np;
+   struct resource *mem;
+   int ret;
+
+   ret = mtk_hdmi_get_all_clk(hdmi, np, clk_names, num_clocks);
+   if (ret) {
+   dev_err(dev, "Failed to get all clks\n");
+   return ret;
+   }
+
+   ret = mtk_hdmi_get_cec_dev(hdmi, dev, np);
+   if (ret) {
+   if (ret == -ENOTSUPP)
+   dev_info(dev, "No CEC node found, continuing without");
+   else

[PATCH v3 03/12] drm/mediatek: hdmi: use a regmap instead of iomem

2022-11-04 Thread Guillaume Ranquet
To prepare support for newer chips that need to share their address
range with a dedicated ddc driver, use a regmap.

Signed-off-by: Guillaume Ranquet 
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 43 +++--
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 4c80b6896dc3..9b02b30a193a 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -171,7 +171,7 @@ struct mtk_hdmi {
u32 ibias_up;
struct regmap *sys_regmap;
unsigned int sys_offset;
-   void __iomem *regs;
+   struct regmap *regs;
enum hdmi_colorspace csp;
struct hdmi_audio_param aud_param;
bool audio_enable;
@@ -187,44 +187,29 @@ static inline struct mtk_hdmi 
*hdmi_ctx_from_bridge(struct drm_bridge *b)
return container_of(b, struct mtk_hdmi, bridge);
 }
 
-static u32 mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset)
+static int mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset, u32 *val)
 {
-   return readl(hdmi->regs + offset);
+   return regmap_read(hdmi->regs, offset, val);
 }
 
 static void mtk_hdmi_write(struct mtk_hdmi *hdmi, u32 offset, u32 val)
 {
-   writel(val, hdmi->regs + offset);
+   regmap_write(hdmi->regs, offset, val);
 }
 
 static void mtk_hdmi_clear_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits)
 {
-   void __iomem *reg = hdmi->regs + offset;
-   u32 tmp;
-
-   tmp = readl(reg);
-   tmp &= ~bits;
-   writel(tmp, reg);
+   regmap_clear_bits(hdmi->regs, offset, bits);
 }
 
 static void mtk_hdmi_set_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits)
 {
-   void __iomem *reg = hdmi->regs + offset;
-   u32 tmp;
-
-   tmp = readl(reg);
-   tmp |= bits;
-   writel(tmp, reg);
+   regmap_set_bits(hdmi->regs, offset, bits);
 }
 
 static void mtk_hdmi_mask(struct mtk_hdmi *hdmi, u32 offset, u32 val, u32 mask)
 {
-   void __iomem *reg = hdmi->regs + offset;
-   u32 tmp;
-
-   tmp = readl(reg);
-   tmp = (tmp & ~mask) | (val & mask);
-   writel(tmp, reg);
+   regmap_update_bits(hdmi->regs, offset, mask, val);
 }
 
 static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black)
@@ -473,7 +458,7 @@ static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi 
*hdmi,
 {
u32 val;
 
-   val = mtk_hdmi_read(hdmi, GRL_CFG0);
+   mtk_hdmi_read(hdmi, GRL_CFG0, &val);
val &= ~(CFG0_W_LENGTH_MASK | CFG0_I2S_MODE_MASK);
 
switch (i2s_fmt) {
@@ -565,7 +550,7 @@ static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi 
*hdmi,
 {
u32 val;
 
-   val = mtk_hdmi_read(hdmi, GRL_CFG1);
+   mtk_hdmi_read(hdmi, GRL_CFG1, &val);
if (input_type == HDMI_AUD_INPUT_I2S &&
(val & CFG1_SPDIF) == CFG1_SPDIF) {
val &= ~CFG1_SPDIF;
@@ -596,7 +581,7 @@ static void mtk_hdmi_hw_aud_src_reenable(struct mtk_hdmi 
*hdmi)
 {
u32 val;
 
-   val = mtk_hdmi_read(hdmi, GRL_MIX_CTRL);
+   mtk_hdmi_read(hdmi, GRL_MIX_CTRL, &val);
if (val & MIX_CTRL_SRC_EN) {
val &= ~MIX_CTRL_SRC_EN;
mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);
@@ -610,7 +595,7 @@ static void mtk_hdmi_hw_aud_src_disable(struct mtk_hdmi 
*hdmi)
 {
u32 val;
 
-   val = mtk_hdmi_read(hdmi, GRL_MIX_CTRL);
+   mtk_hdmi_read(hdmi, GRL_MIX_CTRL, &val);
val &= ~MIX_CTRL_SRC_EN;
mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);
mtk_hdmi_write(hdmi, GRL_SHIFT_L1, 0x00);
@@ -621,7 +606,7 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,
 {
u32 val;
 
-   val = mtk_hdmi_read(hdmi, GRL_CFG5);
+   mtk_hdmi_read(hdmi, GRL_CFG5, &val);
val &= CFG5_CD_RATIO_MASK;
 
switch (mclk) {
@@ -1427,7 +1412,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
struct device_node *cec_np, *remote, *i2c_np;
struct platform_device *cec_pdev;
struct regmap *regmap;
-   struct resource *mem;
int ret;
 
ret = mtk_hdmi_get_all_clk(hdmi, np);
@@ -1473,8 +1457,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
}
hdmi->sys_regmap = regmap;
 
-   mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   hdmi->regs = devm_ioremap_resource(dev, mem);
+   hdmi->regs = device_node_to_regmap(dev->of_node);
if (IS_ERR(hdmi->regs)) {
ret = PTR_ERR(hdmi->regs);
goto put_device;

-- 
b4 0.11.0-dev


[PATCH v3 02/12] dt-bindings: display: mediatek: add MT8195 hdmi bindings

2022-11-04 Thread Guillaume Ranquet
Add mt8195 SoC bindings for hdmi and hdmi-ddc

On mt8195 the ddc i2c controller is part of the hdmi IP block and thus has no
specific register range, power domain or interrupt, making it simpler
than its the legacy "mediatek,hdmi-ddc" binding.

Signed-off-by: Guillaume Ranquet 
---
 .../bindings/display/mediatek/mediatek,hdmi.yaml   | 61 ++
 .../display/mediatek/mediatek,mt8195-hdmi-ddc.yaml | 51 ++
 2 files changed, 101 insertions(+), 11 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml
index bdaf0b51e68c..9710b7b6e9bf 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.yaml
@@ -21,6 +21,7 @@ properties:
   - mediatek,mt7623-hdmi
   - mediatek,mt8167-hdmi
   - mediatek,mt8173-hdmi
+  - mediatek,mt8195-hdmi
 
   reg:
 maxItems: 1
@@ -29,18 +30,12 @@ properties:
 maxItems: 1
 
   clocks:
-items:
-  - description: Pixel Clock
-  - description: HDMI PLL
-  - description: Bit Clock
-  - description: S/PDIF Clock
+minItems: 4
+maxItems: 4
 
   clock-names:
-items:
-  - const: pixel
-  - const: pll
-  - const: bclk
-  - const: spdif
+minItems: 4
+maxItems: 4
 
   phys:
 maxItems: 1
@@ -58,6 +53,9 @@ properties:
 description: |
   phandle link and register offset to the system configuration registers.
 
+  power-domains:
+maxItems: 1
+
   ports:
 $ref: /schemas/graph.yaml#/properties/ports
 
@@ -86,9 +84,50 @@ required:
   - clock-names
   - phys
   - phy-names
-  - mediatek,syscon-hdmi
   - ports
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: mediatek,mt8195-hdmi
+then:
+  properties:
+clocks:
+  items:
+- description: APB
+- description: HDCP
+- description: HDCP 24M
+- description: Split HDMI
+clock-names:
+  items:
+- const: hdmi_apb_sel
+- const: hdcp_sel
+- const: hdcp24_sel
+- const: split_hdmi
+
+  required:
+- power-domains
+else:
+  properties:
+clocks:
+  items:
+- description: Pixel Clock
+- description: HDMI PLL
+- description: Bit Clock
+- description: S/PDIF Clock
+
+clock-names:
+  items:
+- const: pixel
+- const: pll
+- const: bclk
+- const: spdif
+
+  required:
+- mediatek,syscon-hdmi
+
 additionalProperties: false
 
 examples:
diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
new file mode 100644
index ..2dc273689584
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: 
http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek HDMI DDC for mt8195
+
+maintainers:
+  - CK Hu 
+  - Jitao shi 
+
+description: |
+  The HDMI DDC i2c controller is used to interface with the HDMI DDC pins.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt8195-hdmi-ddc
+
+  clocks:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: ddc
+
+  mediatek,hdmi:
+$ref: /schemas/types.yaml#/definitions/phandle
+description:
+  A phandle to the mt8195 hdmi controller
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+hdmiddc0: i2c {
+  compatible = "mediatek,mt8195-hdmi-ddc";
+  mediatek,hdmi = <&hdmi0>;
+  clocks = <&clk26m>;
+  clock-names = "ddc";
+};
+
+...

-- 
b4 0.11.0-dev


[PATCH v3 01/12] dt-bindings: phy: mediatek: hdmi-phy: Add mt8195 compatible

2022-11-04 Thread Guillaume Ranquet
Add a compatible for the HDMI PHY on MT8195

Acked-by: Krzysztof Kozlowski 
Signed-off-by: Guillaume Ranquet 
---
 Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml 
b/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml
index 0d94950b84ca..71c75a11e189 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml
@@ -28,6 +28,7 @@ properties:
   - const: mediatek,mt2701-hdmi-phy
   - const: mediatek,mt2701-hdmi-phy
   - const: mediatek,mt8173-hdmi-phy
+  - const: mediatek,mt8195-hdmi-phy
 
   reg:
 maxItems: 1

-- 
b4 0.11.0-dev


  1   2   3   >