[Bug 214207] Nouveau crash after play youtube video from surf browser

2021-08-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=214207

Alexey Boldyrev (ne-vleza...@yandex.ru) changed:

   What|Removed |Added

   Keywords||opw
 CC||ne-vleza...@yandex.ru

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

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

[Bug 214207] New: Nouveau crash after play youtube video from surf browser

2021-08-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=214207

Bug ID: 214207
   Summary: Nouveau crash after play youtube video from surf
browser
   Product: Drivers
   Version: 2.5
Kernel Version: 5.10.0-8-amd64
  Hardware: x86-64
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: high
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: ne-vleza...@yandex.ru
Regression: No

Log:
[  796.192899] nouveau :01:00.0: fifo: PBDMA0: 0004 [PBENTRY] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd  data 
[  796.192919] nouveau :01:00.0: gr: DATA_ERROR 000d [BEGIN_END_ACTIVE]
ch 7 [003f8f9000 Xorg[1301]] subc 0 class a197 mthd 1614 data 
[  796.391497] nouveau :01:00.0: gr: DATA_ERROR 000c [INVALID_BITFIELD]
ch 7 [003f8f9000 Xorg[1301]] subc 0 class a197 mthd 2384 data 0258
[  796.391511] nouveau :01:00.0: fifo: PBDMA0: 0004 [PBENTRY] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd  data 
[  796.391524] nouveau :01:00.0: gr: TRAP ch 7 [003f8f9000 Xorg[1301]]
[  796.391528] nouveau :01:00.0: gr: DISPATCH 8002
[CLASS_SUBCH_MISMATCH]
[  796.391536] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 000c data 0040
[  796.391548] nouveau :01:00.0: fifo: PBDMA0: 0200 [SEMAPHORE] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 001c data 200503f8
[  796.391564] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0030 data 
[  796.391580] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0034 data 2001054e
[  796.391595] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0038 data 0001
[  796.391610] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 003c data 2003048a
[  796.391625] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0040 data 0320
[  796.391638] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0044 data 0258
[  796.391652] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0048 data 00010001
[  796.391664] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 004c data 200105e7
[  796.391820] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0054 data 20010487
[  796.391833] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0058 data 0fac6881
[  796.391847] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 005c data 8574
[  796.391859] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0060 data 8671
[  796.391872] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0064 data 84b9
[  796.391883] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0068 data 8e04
[  796.391896] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 006c data 800103e4
[  796.391910] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0070 data 20010680
[  796.391923] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0074 data 
[  796.391935] nouveau :01:00.0: fifo: PBDMA0: 0040 [METHODCRC] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 007c data 
[  796.391948] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0084 data 866f
[  796.391960] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0088 data 84e0
[  796.391973] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 008c data 84bb
[  796.391985] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0090 data 20024062
[  796.391999] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0094 data 
[  796.392011] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 0098 data 008e19c0
[  796.392024] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 009c data 20024060
[  796.392037] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 7
[003f8f9000 Xorg[1301]] subc 0 mthd 00a0 data 0020
[  796.392049] nouveau :01:00.0: fifo: PBDMA0: 0020 [METHOD] ch 

Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format

2021-08-27 Thread kernel test robot
Hi Fangzhi,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-intel/for-linux-next]
[also build test WARNING on drm-tip/drm-tip drm-exynos/exynos-drm-next 
tegra-drm/drm/tegra/for-next linus/master v5.14-rc7 next-20210827]
[cannot apply to drm/drm-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Fangzhi-Zuo/Update-128b-132b-MST-Slot-Information/20210828-082044
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: parisc-randconfig-r002-20210827 (attached as .config)
compiler: hppa-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/8232240b519fadd6ad9eb814925e513a15407474
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Fangzhi-Zuo/Update-128b-132b-MST-Slot-Information/20210828-082044
git checkout 8232240b519fadd6ad9eb814925e513a15407474
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross 
ARCH=parisc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/drm_dp_mst_topology.c:4512:6: warning: no previous prototype 
>> for 'drm_dp_mst_update_encoding_cap' [-Wmissing-prototypes]
4512 | void drm_dp_mst_update_encoding_cap(struct drm_dp_mst_topology_mgr 
*mgr, uint8_t link_encoding_cap)
 |  ^~


vim +/drm_dp_mst_update_encoding_cap +4512 drivers/gpu/drm/drm_dp_mst_topology.c

  4511  
> 4512  void drm_dp_mst_update_encoding_cap(struct drm_dp_mst_topology_mgr 
> *mgr, uint8_t link_encoding_cap)
  4513  {
  4514  if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
  4515  mgr->total_avail_slots = 64;
  4516  mgr->start_slot = 0;
  4517  }
  4518  DRM_DEBUG_KMS("%s encoding format determined\n",
  4519(link_encoding_cap == DP_CAP_ANSI_128B132B) ? 
"128b/132b" : "8b/10b");
  4520  }
  4521  EXPORT_SYMBOL(drm_dp_mst_update_encoding_cap);
  4522  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


[PATCH v7 12/17] drm/i915/pxp: Enable PXP power management

2021-08-27 Thread Daniele Ceraolo Spurio
From: "Huang, Sean Z" 

During the power event S3+ sleep/resume, hardware will lose all the
encryption keys for every hardware session, even though the
session state might still be marked as alive after resume. Therefore,
we should consider the session as dead on suspend and invalidate all the
objects. The session will be automatically restarted on the first
protected submission on resume.

v2: runtime suspend also invalidates the keys
v3: fix return codes, simplify rpm ops (Chris), use the new worker func
v4: invalidate the objects on suspend, don't re-create the arb sesson on
resume (delayed to first submission).
v5: move irq changes back to irq patch (Rodrigo)

Signed-off-by: Huang, Sean Z 
Signed-off-by: Daniele Ceraolo Spurio 
Cc: Chris Wilson 
Cc: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/Makefile|  1 +
 drivers/gpu/drm/i915/gt/intel_gt_pm.c| 15 +++-
 drivers/gpu/drm/i915/i915_drv.c  |  2 +
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c  | 40 
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h  | 23 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 38 ++-
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c |  9 +
 8 files changed, 118 insertions(+), 11 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 728e5947d6eb..6f6cbbe98b96 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -285,6 +285,7 @@ i915-$(CONFIG_DRM_I915_PXP) += \
pxp/intel_pxp.o \
pxp/intel_pxp_cmd.o \
pxp/intel_pxp_irq.o \
+   pxp/intel_pxp_pm.o \
pxp/intel_pxp_session.o \
pxp/intel_pxp_tee.o
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index dea8e2479897..0fd1acab68c0 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -18,6 +18,7 @@
 #include "intel_rc6.h"
 #include "intel_rps.h"
 #include "intel_wakeref.h"
+#include "pxp/intel_pxp_pm.h"
 
 static void user_forcewake(struct intel_gt *gt, bool suspend)
 {
@@ -262,6 +263,8 @@ int intel_gt_resume(struct intel_gt *gt)
 
intel_uc_resume(>uc);
 
+   intel_pxp_resume(>pxp);
+
user_forcewake(gt, false);
 
 out_fw:
@@ -296,6 +299,7 @@ void intel_gt_suspend_prepare(struct intel_gt *gt)
user_forcewake(gt, true);
wait_for_suspend(gt);
 
+   intel_pxp_suspend(>pxp);
intel_uc_suspend(>uc);
 }
 
@@ -346,6 +350,7 @@ void intel_gt_suspend_late(struct intel_gt *gt)
 
 void intel_gt_runtime_suspend(struct intel_gt *gt)
 {
+   intel_pxp_suspend(>pxp);
intel_uc_runtime_suspend(>uc);
 
GT_TRACE(gt, "\n");
@@ -353,11 +358,19 @@ void intel_gt_runtime_suspend(struct intel_gt *gt)
 
 int intel_gt_runtime_resume(struct intel_gt *gt)
 {
+   int ret;
+
GT_TRACE(gt, "\n");
intel_gt_init_swizzling(gt);
intel_ggtt_restore_fences(gt->ggtt);
 
-   return intel_uc_runtime_resume(>uc);
+   ret = intel_uc_runtime_resume(>uc);
+   if (ret)
+   return ret;
+
+   intel_pxp_resume(>pxp);
+
+   return 0;
 }
 
 static ktime_t __intel_gt_get_awake_time(const struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 59fb4c710c8c..d5bcc70a22d4 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -67,6 +67,8 @@
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_rc6.h"
 
+#include "pxp/intel_pxp_pm.h"
+
 #include "i915_debugfs.h"
 #include "i915_drv.h"
 #include "i915_ioc32.h"
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
index 340f20d130a8..9e5847c653f2 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -9,6 +9,7 @@
 #include "gt/intel_gt_irq.h"
 #include "i915_irq.h"
 #include "i915_reg.h"
+#include "intel_runtime_pm.h"
 
 /**
  * intel_pxp_irq_handler - Handles PXP interrupts.
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
new file mode 100644
index ..4507756b2977
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+
+#include "intel_pxp.h"
+#include "intel_pxp_irq.h"
+#include "intel_pxp_pm.h"
+#include "intel_pxp_session.h"
+
+void intel_pxp_suspend(struct intel_pxp *pxp)
+{
+   if (!intel_pxp_is_enabled(pxp))
+   return;
+
+   pxp->arb_is_valid = false;
+
+   /* invalidate protected objects */
+   intel_pxp_invalidate(pxp);
+
+   intel_pxp_fini_hw(pxp);
+
+   pxp->hw_state_invalidated = false;
+}
+
+void intel_pxp_resume(struct intel_pxp *pxp)
+{
+   if 

[PATCH v7 11/17] drm/i915/pxp: start the arb session on demand

2021-08-27 Thread Daniele Ceraolo Spurio
Now that we can handle destruction and re-creation of the arb session,
we can postpone the start of the session to the first submission that
requires it, to avoid keeping it running with no user.

Signed-off-by: Daniele Ceraolo Spurio 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c  |  4 ++-
 drivers/gpu/drm/i915/pxp/intel_pxp.c | 37 +---
 drivers/gpu/drm/i915/pxp/intel_pxp.h |  5 +--
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c |  2 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c |  6 ++--
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 10 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h   |  2 ++
 7 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index f411e26768fd..065c87e8031f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -267,7 +267,9 @@ static int proto_context_set_protected(struct 
drm_i915_private *i915,
 * which in turn requires the device to be active.
 */
pc->pxp_wakeref = intel_runtime_pm_get(>runtime_pm);
-   ret = intel_pxp_wait_for_arb_start(>gt.pxp);
+
+   if (!intel_pxp_is_active(>gt.pxp))
+   ret = intel_pxp_start(>gt.pxp);
}
 
return ret;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 9beac9746c00..045a8402ebb3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -79,6 +79,7 @@ void intel_pxp_init(struct intel_pxp *pxp)
init_completion(>termination);
complete_all(>termination);
 
+   mutex_init(>arb_mutex);
INIT_WORK(>session_work, intel_pxp_session_work);
 
ret = create_vcs_context(pxp);
@@ -115,7 +116,7 @@ void intel_pxp_mark_termination_in_progress(struct 
intel_pxp *pxp)
reinit_completion(>termination);
 }
 
-static void intel_pxp_queue_termination(struct intel_pxp *pxp)
+static void pxp_queue_termination(struct intel_pxp *pxp)
 {
struct intel_gt *gt = pxp_to_gt(pxp);
 
@@ -134,31 +135,41 @@ static void intel_pxp_queue_termination(struct intel_pxp 
*pxp)
  * the arb session is restarted from the irq work when we receive the
  * termination completion interrupt
  */
-int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
+int intel_pxp_start(struct intel_pxp *pxp)
 {
+   int ret = 0;
+
if (!intel_pxp_is_enabled(pxp))
-   return 0;
+   return -ENODEV;
+
+   mutex_lock(>arb_mutex);
+
+   if (pxp->arb_is_valid)
+   goto unlock;
+
+   pxp_queue_termination(pxp);
 
if (!wait_for_completion_timeout(>termination,
-msecs_to_jiffies(100)))
-   return -ETIMEDOUT;
+   msecs_to_jiffies(100))) {
+   ret = -ETIMEDOUT;
+   goto unlock;
+   }
+
+   /* make sure the compiler doesn't optimize the double access */
+   barrier();
 
if (!pxp->arb_is_valid)
-   return -EIO;
+   ret = -EIO;
 
-   return 0;
+unlock:
+   mutex_unlock(>arb_mutex);
+   return ret;
 }
 
 void intel_pxp_init_hw(struct intel_pxp *pxp)
 {
kcr_pxp_enable(pxp_to_gt(pxp));
intel_pxp_irq_enable(pxp);
-
-   /*
-* the session could've been attacked while we weren't loaded, so
-* handle it as if it was and re-create it.
-*/
-   intel_pxp_queue_termination(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index f942bdd2af0c..424fe00a91fb 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -34,7 +34,8 @@ void intel_pxp_init_hw(struct intel_pxp *pxp);
 void intel_pxp_fini_hw(struct intel_pxp *pxp);
 
 void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
-int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
+
+int intel_pxp_start(struct intel_pxp *pxp);
 
 int intel_pxp_key_check(struct intel_pxp *pxp, struct drm_i915_gem_object 
*obj);
 
@@ -48,7 +49,7 @@ static inline void intel_pxp_fini(struct intel_pxp *pxp)
 {
 }
 
-static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
+static inline int intel_pxp_start(struct intel_pxp *pxp)
 {
return -ENODEV;
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
index 46eca1e81b9b..340f20d130a8 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -31,7 +31,7 @@ void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
   GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT)) {
/* immediately mark PXP as inactive on termination */

[PATCH v7 17/17] drm/i915/pxp: enable PXP for integrated Gen12

2021-08-27 Thread Daniele Ceraolo Spurio
Note that discrete cards can support PXP as well, but we haven't tested
on those yet so keeping it disabled for now.

Signed-off-by: Daniele Ceraolo Spurio 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/i915_pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 146f7e39182a..3ec52e42e208 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -865,6 +865,7 @@ static const struct intel_device_info jsl_info = {
}, \
TGL_CURSOR_OFFSETS, \
.has_global_mocs = 1, \
+   .has_pxp = 1, \
.display.has_dsb = 1
 
 static const struct intel_device_info tgl_info = {
@@ -891,6 +892,7 @@ static const struct intel_device_info rkl_info = {
 #define DGFX_FEATURES \
.memory_regions = REGION_SMEM | REGION_LMEM | REGION_STOLEN_LMEM, \
.has_llc = 0, \
+   .has_pxp = 0, \
.has_snoop = 1, \
.is_dgfx = 1
 
-- 
2.25.1



[PATCH v7 14/17] drm/i915/pxp: black pixels on pxp disabled

2021-08-27 Thread Daniele Ceraolo Spurio
From: Anshuman Gupta 

When protected sufaces has flipped and pxp session is disabled,
display black pixels by using plane color CTM correction.

v2:
- Display black pixels in async flip too.

v3:
- Removed the black pixels logic for async flip. [Ville]
- Used plane state to force black pixels. [Ville]

v4 (Daniele): update pxp_is_borked check.

v5: rebase on top of v9 plane decryption moving the decrypt check
(Juston)

Cc: Ville Syrjälä 
Cc: Gaurav Kumar 
Cc: Shankar Uma 
Signed-off-by: Anshuman Gupta 
Signed-off-by: Daniele Ceraolo Spurio 
Signed-off-by: Juston Li 
Reviewed-by: Rodrigo Vivi  #v4
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_display.c  | 12 -
 .../drm/i915/display/intel_display_types.h|  3 ++
 .../drm/i915/display/skl_universal_plane.c| 36 ++-
 drivers/gpu/drm/i915/i915_reg.h   | 46 +++
 4 files changed, 94 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index f04d98fcea46..146c87440cc6 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -9157,6 +9157,11 @@ static bool bo_has_valid_encryption(struct 
drm_i915_gem_object *obj)
return intel_pxp_key_check(>gt.pxp, obj, false) == 0;
 }
 
+static bool pxp_is_borked(struct drm_i915_gem_object *obj)
+{
+   return i915_gem_object_is_protected(obj) && 
!bo_has_valid_encryption(obj);
+}
+
 static int intel_atomic_check_planes(struct intel_atomic_state *state)
 {
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
@@ -9218,10 +9223,13 @@ static int intel_atomic_check_planes(struct 
intel_atomic_state *state)
new_plane_state = intel_atomic_get_new_plane_state(state, 
plane);
old_plane_state = intel_atomic_get_old_plane_state(state, 
plane);
fb = new_plane_state->hw.fb;
-   if (fb)
+   if (fb) {
new_plane_state->decrypt = 
bo_has_valid_encryption(intel_fb_obj(fb));
-   else
+   new_plane_state->force_black = 
pxp_is_borked(intel_fb_obj(fb));
+   } else {
new_plane_state->decrypt = old_plane_state->decrypt;
+   new_plane_state->force_black = 
old_plane_state->force_black;
+   }
}
 
return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 6d4ea1d5bf7b..05d2e6676387 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -632,6 +632,9 @@ struct intel_plane_state {
/* Plane pxp decryption state */
bool decrypt;
 
+   /* Plane state to display black pixels when pxp is borked */
+   bool force_black;
+
/* plane control register */
u32 ctl;
 
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 55e3f093b951..c4adcb3e12b3 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1002,6 +1002,33 @@ static u32 skl_surf_address(const struct 
intel_plane_state *plane_state,
}
 }
 
+static void intel_load_plane_csc_black(struct intel_plane *intel_plane)
+{
+   struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
+   enum pipe pipe = intel_plane->pipe;
+   enum plane_id plane = intel_plane->id;
+   u16 postoff = 0;
+
+   drm_dbg_kms(_priv->drm, "plane color CTM to black  %s:%d\n",
+   intel_plane->base.name, plane);
+   intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 0), 0);
+   intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 1), 0);
+
+   intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 2), 0);
+   intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 3), 0);
+
+   intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 4), 0);
+   intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 5), 0);
+
+   intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 0), 0);
+   intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 1), 0);
+   intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 2), 0);
+
+   intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 0), postoff);
+   intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 1), postoff);
+   intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 2), postoff);
+}
+
 static void
 skl_program_plane(struct intel_plane *plane,
  const struct intel_crtc_state *crtc_state,
@@ -1115,14 +1142,21 @@ skl_program_plane(struct intel_plane *plane,
 */
intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
plane_surf = 

[PATCH v7 16/17] drm/i915/pxp: add PXP documentation

2021-08-27 Thread Daniele Ceraolo Spurio
Now that all the pieces are in place we can add a description of how the
feature works. Also modify the comments in struct intel_pxp into
kerneldoc.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Daniel Vetter 
Cc: Rodrigo Vivi 
---
 Documentation/gpu/i915.rst |  8 
 drivers/gpu/drm/i915/pxp/intel_pxp.c   | 28 +
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 47 --
 3 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index 204ebdaadb45..2e267ecd7651 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -474,6 +474,14 @@ Object Tiling IOCTLs
 .. kernel-doc:: drivers/gpu/drm/i915/gem/i915_gem_tiling.c
:doc: buffer object tiling
 
+Protected Objects
+-
+
+.. kernel-doc:: drivers/gpu/drm/i915/pxp/intel_pxp.c
+   :doc: PXP
+
+.. kernel-doc:: drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+
 Microcontrollers
 
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 8c73ab0f2e7c..29e011cf7139 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -11,6 +11,34 @@
 #include "gt/intel_context.h"
 #include "i915_drv.h"
 
+/**
+ * DOC: PXP
+ *
+ * PXP (Protected Xe Path) is a Gen12+ feature that allows execution and
+ * flip to display of protected (i.e. encrypted) objects. The SW support is
+ * enabled via the CONFIG_DRM_I915_PXP kconfig.
+ *
+ * Some of the PXP setup operations are performed by the Management Engine,
+ * which is handled by the mei driver; communication between i915 and mei is
+ * performed via the mei_pxp component module.
+ *
+ * Objects can opt-in to PXP encryption at creation time via the
+ * I915_GEM_CREATE_EXT_PROTECTED_CONTENT create_ext flag. For objects to be
+ * correctly protected they must be used in conjunction with a context created
+ * with the I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. See the documentation
+ * of those two uapi flags for details and restrictions.
+ *
+ * Protected objects are tied to a pxp session; currently we only support one
+ * session, which i915 manages and whose index is available in the uapi
+ * (I915_PROTECTED_CONTENT_DEFAULT_SESSION) for use in instructions targeting
+ * protected objects.
+ * The session is invalidated by the HW when certain events occur (e.g.
+ * suspend/resume). When this happens, all the objects that were used with the
+ * session are marked as invalid and all contexts marked as using protected
+ * content are banned. Any further attempt at using them in an execbuf call is
+ * rejected, while flips are converted to black frames.
+ */
+
 /* KCR register definitions */
 #define KCR_INIT _MMIO(0x320f0)
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index ae24064bb57e..73ef7d1754e1 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -16,42 +16,65 @@
 struct intel_context;
 struct i915_pxp_component;
 
+/**
+ * struct intel_pxp - pxp state
+ */
 struct intel_pxp {
+   /**
+* @pxp_component: i915_pxp_component struct of the bound mei_pxp
+* module. Only set and cleared inside component bind/unbind functions,
+* which are protected by _mutex.
+*/
struct i915_pxp_component *pxp_component;
+   /**
+* @pxp_component_added: track if the pxp component has been added.
+* Set and cleared in tee init and fini functions respectively.
+*/
bool pxp_component_added;
 
+   /** @ce: kernel-owned context used for PXP operations */
struct intel_context *ce;
 
-   /*
+   /** @arb_mutex: protects arb session start */
+   struct mutex arb_mutex;
+   /**
+* @arb_is_valid: tracks arb session status.
 * After a teardown, the arb session can still be in play on the HW
 * even if the keys are gone, so we can't rely on the HW state of the
 * session to know if it's valid and need to track the status in SW.
 */
-   struct mutex arb_mutex; /* protects arb session start */
bool arb_is_valid;
 
-   /*
-* Keep track of which key instance we're on, so we can use it to
-* determine if an object was created using the current key or a
+   /**
+* @key_instance: tracks which key instance we're on, so we can use it
+* to determine if an object was created using the current key or a
 * previous one.
 */
u32 key_instance;
 
-   struct mutex tee_mutex; /* protects the tee channel binding */
+   /** @tee_mutex: protects the tee channel binding and messaging. */
+   struct mutex tee_mutex;
 
-   /*
-* If the HW perceives an attack on the integrity of the encryption it
-* will invalidate the keys and expect SW to re-initialize the session.
-* We keep track of 

[PATCH v7 15/17] drm/i915/pxp: add pxp debugfs

2021-08-27 Thread Daniele Ceraolo Spurio
2 debugfs files, one to query the current status of the pxp session and one
to trigger an invalidation for testing.

Signed-off-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/Makefile|  1 +
 drivers/gpu/drm/i915/gt/debugfs_gt.c |  2 +
 drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c | 78 
 drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.h | 21 ++
 4 files changed, 102 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 6f6cbbe98b96..9a44d6f01e3b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -284,6 +284,7 @@ i915-y += i915_perf.o
 i915-$(CONFIG_DRM_I915_PXP) += \
pxp/intel_pxp.o \
pxp/intel_pxp_cmd.o \
+   pxp/intel_pxp_debugfs.o \
pxp/intel_pxp_irq.o \
pxp/intel_pxp_pm.o \
pxp/intel_pxp_session.o \
diff --git a/drivers/gpu/drm/i915/gt/debugfs_gt.c 
b/drivers/gpu/drm/i915/gt/debugfs_gt.c
index 591eb60785db..c27847ddb796 100644
--- a/drivers/gpu/drm/i915/gt/debugfs_gt.c
+++ b/drivers/gpu/drm/i915/gt/debugfs_gt.c
@@ -9,6 +9,7 @@
 #include "debugfs_gt.h"
 #include "debugfs_gt_pm.h"
 #include "intel_sseu_debugfs.h"
+#include "pxp/intel_pxp_debugfs.h"
 #include "uc/intel_uc_debugfs.h"
 #include "i915_drv.h"
 
@@ -28,6 +29,7 @@ void debugfs_gt_register(struct intel_gt *gt)
intel_sseu_debugfs_register(gt, root);
 
intel_uc_debugfs_register(>uc, root);
+   intel_pxp_debugfs_register(>pxp, root);
 }
 
 void intel_gt_debugfs_register_files(struct dentry *root,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
new file mode 100644
index ..a26e4396ba6c
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include 
+#include 
+
+#include "gt/debugfs_gt.h"
+#include "pxp/intel_pxp.h"
+#include "pxp/intel_pxp_irq.h"
+#include "i915_drv.h"
+
+static int pxp_info_show(struct seq_file *m, void *data)
+{
+   struct intel_pxp *pxp = m->private;
+   struct drm_printer p = drm_seq_file_printer(m);
+   bool enabled = intel_pxp_is_enabled(pxp);
+
+   if (!enabled) {
+   drm_printf(, "pxp disabled\n");
+   return 0;
+   }
+
+   drm_printf(, "active: %s\n", yesno(intel_pxp_is_active(pxp)));
+   drm_printf(, "instance counter: %u\n", pxp->key_instance);
+
+   return 0;
+}
+DEFINE_GT_DEBUGFS_ATTRIBUTE(pxp_info);
+
+static int pxp_inval_get(void *data, u64 *val)
+{
+   /* nothing to read */
+   return -EPERM;
+}
+
+static int pxp_inval_set(void *data, u64 val)
+{
+   struct intel_pxp *pxp = data;
+   struct intel_gt *gt = pxp_to_gt(pxp);
+
+   if (!intel_pxp_is_active(pxp))
+   return -ENODEV;
+
+   /* simulate an invalidation interrupt */
+   spin_lock_irq(>irq_lock);
+   intel_pxp_irq_handler(pxp, 
GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT);
+   spin_unlock_irq(>irq_lock);
+
+   if (!wait_for_completion_timeout(>termination,
+msecs_to_jiffies(100)))
+   return -ETIMEDOUT;
+
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pxp_inval_fops, pxp_inval_get, pxp_inval_set, 
"%llx\n");
+void intel_pxp_debugfs_register(struct intel_pxp *pxp, struct dentry *gt_root)
+{
+   static const struct debugfs_gt_file files[] = {
+   { "info", _info_fops, NULL },
+   { "invalidate", _inval_fops, NULL },
+   };
+   struct dentry *root;
+
+   if (!gt_root)
+   return;
+
+   if (!HAS_PXP((pxp_to_gt(pxp)->i915)))
+   return;
+
+   root = debugfs_create_dir("pxp", gt_root);
+   if (IS_ERR(root))
+   return;
+
+   intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), pxp);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.h
new file mode 100644
index ..3b7454d838e9
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#ifndef __INTEL_PXP_DEBUGFS_H__
+#define __INTEL_PXP_DEBUGFS_H__
+
+struct intel_pxp;
+struct dentry;
+
+#ifdef CONFIG_DRM_I915_PXP
+void intel_pxp_debugfs_register(struct intel_pxp *pxp, struct dentry *root);
+#else
+static inline void
+intel_pxp_debugfs_register(struct intel_pxp *pxp, struct dentry *root)
+{
+}
+#endif
+
+#endif /* __INTEL_PXP_DEBUGFS_H__ */
-- 
2.25.1



[PATCH v7 05/17] drm/i915/pxp: Implement funcs to create the TEE channel

2021-08-27 Thread Daniele Ceraolo Spurio
From: "Huang, Sean Z" 

Implement the funcs to create the TEE channel, so kernel can
send the TEE commands directly to TEE for creating the arbitrary
(default) session.

v2: fix locking, don't pollute dev_priv (Chris)

v3: wait for mei PXP component to be bound.

v4: drop the wait, as the component might be bound after i915 load
completes. We'll instead check when sending a tee message.

v5: fix an issue with mei_pxp module removal

Signed-off-by: Huang, Sean Z 
Signed-off-by: Daniele Ceraolo Spurio 
Cc: Chris Wilson 
Reviewed-by: Rodrigo Vivi  #v4
---
 drivers/gpu/drm/i915/Makefile  |  3 +-
 drivers/gpu/drm/i915/pxp/intel_pxp.c   | 13 
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c   | 76 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h   | 14 
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h |  6 ++
 5 files changed, 111 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 157644ef5886..cc9fe99ca5c5 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -282,7 +282,8 @@ i915-y += i915_perf.o
 
 # Protected execution platform (PXP) support
 i915-$(CONFIG_DRM_I915_PXP) += \
-   pxp/intel_pxp.o
+   pxp/intel_pxp.o \
+   pxp/intel_pxp_tee.o
 
 # Post-mortem debug and GPU hang state capture
 i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 7b2053902146..400deaea2d8a 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -3,6 +3,7 @@
  * Copyright(c) 2020 Intel Corporation.
  */
 #include "intel_pxp.h"
+#include "intel_pxp_tee.h"
 #include "gt/intel_context.h"
 #include "i915_drv.h"
 
@@ -50,7 +51,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
if (ret)
return;
 
+   ret = intel_pxp_tee_component_init(pxp);
+   if (ret)
+   goto out_context;
+
drm_info(>i915->drm, "Protected Xe Path (PXP) protected content 
support initialized\n");
+
+   return;
+
+out_context:
+   destroy_vcs_context(pxp);
 }
 
 void intel_pxp_fini(struct intel_pxp *pxp)
@@ -58,5 +68,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
if (!intel_pxp_is_enabled(pxp))
return;
 
+   intel_pxp_tee_component_fini(pxp);
+
destroy_vcs_context(pxp);
+
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
new file mode 100644
index ..2f28f34c721d
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+
+#include 
+#include "drm/i915_pxp_tee_interface.h"
+#include "drm/i915_component.h"
+#include "i915_drv.h"
+#include "intel_pxp.h"
+#include "intel_pxp_tee.h"
+
+static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
+{
+   return _to_i915(i915_kdev)->gt.pxp;
+}
+
+/**
+ * i915_pxp_tee_component_bind - bind function to pass the function pointers 
to pxp_tee
+ * @i915_kdev: pointer to i915 kernel device
+ * @tee_kdev: pointer to tee kernel device
+ * @data: pointer to pxp_tee_master containing the function pointers
+ *
+ * This bind function is called during the system boot or resume from system 
sleep.
+ *
+ * Return: return 0 if successful.
+ */
+static int i915_pxp_tee_component_bind(struct device *i915_kdev,
+  struct device *tee_kdev, void *data)
+{
+   struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
+
+   pxp->pxp_component = data;
+   pxp->pxp_component->tee_dev = tee_kdev;
+
+   return 0;
+}
+
+static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
+ struct device *tee_kdev, void *data)
+{
+   struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
+
+   pxp->pxp_component = NULL;
+}
+
+static const struct component_ops i915_pxp_tee_component_ops = {
+   .bind   = i915_pxp_tee_component_bind,
+   .unbind = i915_pxp_tee_component_unbind,
+};
+
+int intel_pxp_tee_component_init(struct intel_pxp *pxp)
+{
+   int ret;
+   struct intel_gt *gt = pxp_to_gt(pxp);
+   struct drm_i915_private *i915 = gt->i915;
+
+   ret = component_add_typed(i915->drm.dev, _pxp_tee_component_ops,
+ I915_COMPONENT_PXP);
+   if (ret < 0) {
+   drm_err(>drm, "Failed to add PXP component (%d)\n", ret);
+   return ret;
+   }
+
+   pxp->pxp_component_added = true;
+
+   return 0;
+}
+
+void intel_pxp_tee_component_fini(struct intel_pxp *pxp)
+{
+   struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
+
+   if (fetch_and_zero(>pxp_component_added))
+   component_del(i915->drm.dev, 

[PATCH v7 01/17] drm/i915/pxp: Define PXP component interface

2021-08-27 Thread Daniele Ceraolo Spurio
This will be used for communication between the i915 driver and the mei
one. Defining it in a stand-alone patch to avoid circualr dependedencies
between the patches modifying the 2 drivers.

Split out from an original patch from  Huang, Sean Z

v2: rename the component struct (Rodrigo)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Rodrigo Vivi 
Reviewed-by: Rodrigo Vivi 
---
 include/drm/i915_component.h |  1 +
 include/drm/i915_pxp_tee_interface.h | 42 
 2 files changed, 43 insertions(+)
 create mode 100644 include/drm/i915_pxp_tee_interface.h

diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
index 55c3b123581b..c1e2a43d2d1e 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/i915_component.h
@@ -29,6 +29,7 @@
 enum i915_component_type {
I915_COMPONENT_AUDIO = 1,
I915_COMPONENT_HDCP,
+   I915_COMPONENT_PXP
 };
 
 /* MAX_PORT is the number of port
diff --git a/include/drm/i915_pxp_tee_interface.h 
b/include/drm/i915_pxp_tee_interface.h
new file mode 100644
index ..af593ec64469
--- /dev/null
+++ b/include/drm/i915_pxp_tee_interface.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#ifndef _I915_PXP_TEE_INTERFACE_H_
+#define _I915_PXP_TEE_INTERFACE_H_
+
+#include 
+#include 
+
+/**
+ * struct i915_pxp_component_ops - ops for PXP services.
+ * @owner: Module providing the ops
+ * @send: sends data to PXP
+ * @receive: receives data from PXP
+ */
+struct i915_pxp_component_ops {
+   /**
+* @owner: owner of the module provding the ops
+*/
+   struct module *owner;
+
+   int (*send)(struct device *dev, const void *message, size_t size);
+   int (*recv)(struct device *dev, void *buffer, size_t size);
+};
+
+/**
+ * struct i915_pxp_component - Used for communication between i915 and TEE
+ * drivers for the PXP services
+ * @tee_dev: device that provide the PXP service from TEE Bus.
+ * @pxp_ops: Ops implemented by TEE driver, used by i915 driver.
+ */
+struct i915_pxp_component {
+   struct device *tee_dev;
+   const struct i915_pxp_component_ops *ops;
+
+   /* To protect the above members. */
+   struct mutex mutex;
+};
+
+#endif /* _I915_TEE_PXP_INTERFACE_H_ */
-- 
2.25.1



[PATCH v7 07/17] drm/i915/pxp: Create the arbitrary session after boot

2021-08-27 Thread Daniele Ceraolo Spurio
From: "Huang, Sean Z" 

Create the arbitrary session, with the fixed session id 0xf, after
system boot, for the case that application allocates the protected
buffer without establishing any protection session. Because the
hardware requires at least one alive session for protected buffer
creation. This arbitrary session will need to be re-created after
teardown or power event because hardware encryption key won't be
valid after such cases.

The session ID is exposed as part of the uapi so it can be used as part
of userspace commands.

v2: use gt->uncore->rpm (Chris)
v3: s/arb_is_in_play/arb_is_valid (Chris), move set-up to the new
init_hw function
v4: move interface defs to separate header, set arb_is valid to false
on fini (Rodrigo)
v5: handle async component binding

Signed-off-by: Huang, Sean Z 
Signed-off-by: Daniele Ceraolo Spurio 
Cc: Chris Wilson 
Cc: Rodrigo Vivi 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/Makefile |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c  |  7 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.h  |  5 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 74 
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h  | 15 
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c  | 87 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h  |  3 +
 .../drm/i915/pxp/intel_pxp_tee_interface.h| 37 
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h| 10 +++
 include/uapi/drm/i915_drm.h   |  3 +
 10 files changed, 242 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index cc9fe99ca5c5..7e6bc5deb78f 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -283,6 +283,7 @@ i915-y += i915_perf.o
 # Protected execution platform (PXP) support
 i915-$(CONFIG_DRM_I915_PXP) += \
pxp/intel_pxp.o \
+   pxp/intel_pxp_session.o \
pxp/intel_pxp_tee.o
 
 # Post-mortem debug and GPU hang state capture
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 66a98feb33ab..e1370f323126 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -3,6 +3,7 @@
  * Copyright(c) 2020 Intel Corporation.
  */
 #include "intel_pxp.h"
+#include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
 #include "gt/intel_context.h"
 #include "i915_drv.h"
@@ -65,6 +66,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
if (!HAS_PXP(gt->i915))
return;
 
+   mutex_init(>tee_mutex);
+
ret = create_vcs_context(pxp);
if (ret)
return;
@@ -86,6 +89,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
if (!intel_pxp_is_enabled(pxp))
return;
 
+   pxp->arb_is_valid = false;
+
intel_pxp_tee_component_fini(pxp);
 
destroy_vcs_context(pxp);
@@ -94,6 +99,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 void intel_pxp_init_hw(struct intel_pxp *pxp)
 {
kcr_pxp_enable(pxp_to_gt(pxp));
+
+   intel_pxp_create_arb_session(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 5427c3b28aa9..8eeb65af78b1 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -19,6 +19,11 @@ static inline bool intel_pxp_is_enabled(const struct 
intel_pxp *pxp)
return pxp->ce;
 }
 
+static inline bool intel_pxp_is_active(const struct intel_pxp *pxp)
+{
+   return pxp->arb_is_valid;
+}
+
 #ifdef CONFIG_DRM_I915_PXP
 void intel_pxp_init(struct intel_pxp *pxp);
 void intel_pxp_fini(struct intel_pxp *pxp);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
new file mode 100644
index ..3331868f354c
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#include "drm/i915_drm.h"
+#include "i915_drv.h"
+
+#include "intel_pxp.h"
+#include "intel_pxp_session.h"
+#include "intel_pxp_tee.h"
+#include "intel_pxp_types.h"
+
+#define ARB_SESSION I915_PROTECTED_CONTENT_DEFAULT_SESSION /* shorter define */
+
+#define GEN12_KCR_SIP _MMIO(0x32260) /* KCR hwdrm session in play 0-31 */
+
+static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
+{
+   struct intel_gt *gt = pxp_to_gt(pxp);
+   intel_wakeref_t wakeref;
+   u32 sip = 0;
+
+   with_intel_runtime_pm(gt->uncore->rpm, wakeref)
+   sip = intel_uncore_read(gt->uncore, GEN12_KCR_SIP);
+
+   return sip & BIT(id);
+}
+
+static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool 

[PATCH v7 09/17] drm/i915/pxp: Implement PXP irq handler

2021-08-27 Thread Daniele Ceraolo Spurio
From: "Huang, Sean Z" 

The HW will generate a teardown interrupt when session termination is
required, which requires i915 to submit a terminating batch. Once the HW
is done with the termination it will generate another interrupt, at
which point it is safe to re-create the session.

Since the termination and re-creation flow is something we want to
trigger from the driver as well, use a common work function that can be
called both from the irq handler and from the driver set-up flows, which
has the addded benefit of allowing us to skip any extra locks because
the work itself serializes the operations.

v2: use struct completion instead of bool (Chris)
v3: drop locks, clean up functions and improve comments (Chris),
move to common work function.
v4: improve comments, simplify wait logic (Rodrigo)
v5: unconditionally set interrupts, rename state_attacked var (Rodrigo)

Signed-off-by: Huang, Sean Z 
Signed-off-by: Daniele Ceraolo Spurio 
Cc: Chris Wilson 
Cc: Rodrigo Vivi 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/Makefile|  1 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  7 ++
 drivers/gpu/drm/i915/i915_reg.h  |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c | 66 +++--
 drivers/gpu/drm/i915/pxp/intel_pxp.h |  8 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c | 99 
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h | 32 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 54 ++-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h |  5 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c |  8 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h   | 18 
 11 files changed, 283 insertions(+), 16 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 3a12d5ff5402..728e5947d6eb 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -284,6 +284,7 @@ i915-y += i915_perf.o
 i915-$(CONFIG_DRM_I915_PXP) += \
pxp/intel_pxp.o \
pxp/intel_pxp_cmd.o \
+   pxp/intel_pxp_irq.o \
pxp/intel_pxp_session.o \
pxp/intel_pxp_tee.o
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c 
b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index b2de83be4d97..699a74582d32 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -13,6 +13,7 @@
 #include "intel_lrc_reg.h"
 #include "intel_uncore.h"
 #include "intel_rps.h"
+#include "pxp/intel_pxp_irq.h"
 
 static void guc_irq_handler(struct intel_guc *guc, u16 iir)
 {
@@ -64,6 +65,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 
instance,
if (instance == OTHER_GTPM_INSTANCE)
return gen11_rps_irq_handler(>rps, iir);
 
+   if (instance == OTHER_KCR_INSTANCE)
+   return intel_pxp_irq_handler(>pxp, iir);
+
WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
  instance, iir);
 }
@@ -196,6 +200,9 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK,  ~0);
+
+   intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, 0);
+   intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK,  ~0);
 }
 
 void gen11_gt_irq_postinstall(struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8d4cf1e203ab..1d870c059d8c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8098,6 +8098,7 @@ enum {
 /* irq instances for OTHER_CLASS */
 #define OTHER_GUC_INSTANCE 0
 #define OTHER_GTPM_INSTANCE1
+#define OTHER_KCR_INSTANCE 4
 
 #define GEN11_INTR_IDENTITY_REG(x) _MMIO(0x190060 + ((x) * 4))
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 26176d43a02d..b0c7edc10cc3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -2,7 +2,9 @@
 /*
  * Copyright(c) 2020 Intel Corporation.
  */
+#include 
 #include "intel_pxp.h"
+#include "intel_pxp_irq.h"
 #include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
 #include "gt/intel_context.h"
@@ -68,6 +70,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
 
mutex_init(>tee_mutex);
 
+   /*
+* we'll use the completion to check if there is a termination pending,
+* so we start it as completed and we reinit it when a termination
+* is triggered.
+*/
+   init_completion(>termination);
+   complete_all(>termination);
+
+   INIT_WORK(>session_work, intel_pxp_session_work);
+
ret = create_vcs_context(pxp);
if (ret)
return;
@@ -96,19 +108,61 @@ void intel_pxp_fini(struct intel_pxp *pxp)

[PATCH v7 13/17] drm/i915/pxp: Add plane decryption support

2021-08-27 Thread Daniele Ceraolo Spurio
From: Anshuman Gupta 

Add support to enable/disable PLANE_SURF Decryption Request bit.
It requires only to enable plane decryption support when following
condition met.
1. PXP session is enabled.
2. Buffer object is protected.

v2:
- Used gen fb obj user_flags instead gem_object_metadata. [Krishna]

v3:
- intel_pxp_gem_object_status() API changes.

v4: use intel_pxp_is_active (Daniele)

v5: rebase and use the new protected object status checker (Daniele)

v6: used plane state for plane_decryption to handle async flip
as suggested by Ville.

v7: check pxp session while plane decrypt state computation. [Ville]
removed pointless code. [Ville]

v8 (Daniele): update PXP check

v9: move decrypt check after icl_check_nv12_planes() when overlays
have fb set (Juston)

v10 (Daniele): update PXP check again to match rework in earlier patches and
don't consider protection valid if the object has not been used in an
execbuf beforehand.

Cc: Bommu Krishnaiah 
Cc: Huang Sean Z 
Cc: Gaurav Kumar 
Cc: Ville Syrjälä 
Signed-off-by: Anshuman Gupta 
Signed-off-by: Daniele Ceraolo Spurio 
Signed-off-by: Juston Li 
Reviewed-by: Rodrigo Vivi  #v8
Reviewed-by: Uma Shankar  #v9
---
 drivers/gpu/drm/i915/display/intel_display.c  | 26 +++
 .../drm/i915/display/intel_display_types.h|  3 +++
 .../drm/i915/display/skl_universal_plane.c| 15 ---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|  2 +-
 drivers/gpu/drm/i915/i915_reg.h   |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c  |  9 ---
 drivers/gpu/drm/i915/pxp/intel_pxp.h  |  7 +++--
 7 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index fe5ad599c218..f04d98fcea46 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -70,6 +70,8 @@
 #include "gt/intel_rps.h"
 #include "gt/gen8_ppgtt.h"
 
+#include "pxp/intel_pxp.h"
+
 #include "g4x_dp.h"
 #include "g4x_hdmi.h"
 #include "i915_drv.h"
@@ -9148,13 +9150,23 @@ static int intel_bigjoiner_add_affected_planes(struct 
intel_atomic_state *state)
return 0;
 }
 
+static bool bo_has_valid_encryption(struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
+   return intel_pxp_key_check(>gt.pxp, obj, false) == 0;
+}
+
 static int intel_atomic_check_planes(struct intel_atomic_state *state)
 {
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
struct intel_plane_state *plane_state;
struct intel_plane *plane;
+   struct intel_plane_state *new_plane_state;
+   struct intel_plane_state *old_plane_state;
struct intel_crtc *crtc;
+   const struct drm_framebuffer *fb;
int i, ret;
 
ret = icl_add_linked_planes(state);
@@ -9202,6 +9214,16 @@ static int intel_atomic_check_planes(struct 
intel_atomic_state *state)
return ret;
}
 
+   for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+   new_plane_state = intel_atomic_get_new_plane_state(state, 
plane);
+   old_plane_state = intel_atomic_get_old_plane_state(state, 
plane);
+   fb = new_plane_state->hw.fb;
+   if (fb)
+   new_plane_state->decrypt = 
bo_has_valid_encryption(intel_fb_obj(fb));
+   else
+   new_plane_state->decrypt = old_plane_state->decrypt;
+   }
+
return 0;
 }
 
@@ -9488,6 +9510,10 @@ static int intel_atomic_check_async(struct 
intel_atomic_state *state)
drm_dbg_kms(>drm, "Color range cannot be changed 
in async flip\n");
return -EINVAL;
}
+
+   /* plane decryption is allow to change only in synchronous 
flips */
+   if (old_plane_state->decrypt != new_plane_state->decrypt)
+   return -EINVAL;
}
 
return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index c7bcf9183447..6d4ea1d5bf7b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -629,6 +629,9 @@ struct intel_plane_state {
 
struct intel_fb_view view;
 
+   /* Plane pxp decryption state */
+   bool decrypt;
+
/* plane control register */
u32 ctl;
 
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 724e7b04f3b6..55e3f093b951 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -18,6 +18,7 @@
 #include "intel_sprite.h"
 #include "skl_scaler.h"
 #include "skl_universal_plane.h"
+#include "pxp/intel_pxp.h"
 
 

[PATCH v7 04/17] drm/i915/pxp: allocate a vcs context for pxp usage

2021-08-27 Thread Daniele Ceraolo Spurio
The context is required to send the session termination commands to the
VCS, which will be implemented in a follow-up patch. We can also use the
presence of the context as a check of pxp initialization completion.

v2: use perma-pinned context (Chris)
v3: rename pinned_context functions (Chris)
v4: split export of pinned_context functions to a separate patch (Rodrigo)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Chris Wilson 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/Makefile  |  4 ++
 drivers/gpu/drm/i915/gt/intel_engine.h |  2 +
 drivers/gpu/drm/i915/gt/intel_gt.c |  5 ++
 drivers/gpu/drm/i915/gt/intel_gt_types.h   |  3 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.c   | 62 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.h   | 35 
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 15 ++
 7 files changed, 126 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_types.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 23612c3a1922..157644ef5886 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -280,6 +280,10 @@ i915-y += \
 
 i915-y += i915_perf.o
 
+# Protected execution platform (PXP) support
+i915-$(CONFIG_DRM_I915_PXP) += \
+   pxp/intel_pxp.o
+
 # Post-mortem debug and GPU hang state capture
 i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
 i915-$(CONFIG_DRM_I915_SELFTEST) += \
diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h 
b/drivers/gpu/drm/i915/gt/intel_engine.h
index 87579affb952..eed4634c08cd 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -175,6 +175,8 @@ intel_write_status_page(struct intel_engine_cs *engine, int 
reg, u32 value)
 #define I915_GEM_HWS_SEQNO 0x40
 #define I915_GEM_HWS_SEQNO_ADDR(I915_GEM_HWS_SEQNO * 
sizeof(u32))
 #define I915_GEM_HWS_MIGRATE   (0x42 * sizeof(u32))
+#define I915_GEM_HWS_PXP   0x60
+#define I915_GEM_HWS_PXP_ADDR  (I915_GEM_HWS_PXP * sizeof(u32))
 #define I915_GEM_HWS_SCRATCH   0x80
 
 #define I915_HWS_CSB_BUF0_INDEX0x10
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index 62d40c986642..162f48fd705f 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -21,6 +21,7 @@
 #include "intel_uncore.h"
 #include "intel_pm.h"
 #include "shmem_utils.h"
+#include "pxp/intel_pxp.h"
 
 void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915)
 {
@@ -710,6 +711,8 @@ int intel_gt_init(struct intel_gt *gt)
 
intel_migrate_init(>migrate, gt);
 
+   intel_pxp_init(>pxp);
+
goto out_fw;
 err_gt:
__intel_gt_disable(gt);
@@ -745,6 +748,8 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
 
intel_rps_driver_unregister(>rps);
 
+   intel_pxp_fini(>pxp);
+
/*
 * Upon unregistering the device to prevent any new users, cancel
 * all in-flight requests so that we can quickly unbind the active
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h 
b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index a81e21bf1bd1..ad34c77c8571 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -26,6 +26,7 @@
 #include "intel_rps_types.h"
 #include "intel_migrate_types.h"
 #include "intel_wakeref.h"
+#include "pxp/intel_pxp_types.h"
 
 struct drm_i915_private;
 struct i915_ggtt;
@@ -192,6 +193,8 @@ struct intel_gt {
 
unsigned long mslice_mask;
} info;
+
+   struct intel_pxp pxp;
 };
 
 enum intel_gt_scratch_field {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
new file mode 100644
index ..7b2053902146
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+#include "intel_pxp.h"
+#include "gt/intel_context.h"
+#include "i915_drv.h"
+
+static int create_vcs_context(struct intel_pxp *pxp)
+{
+   static struct lock_class_key pxp_lock;
+   struct intel_gt *gt = pxp_to_gt(pxp);
+   struct intel_engine_cs *engine;
+   struct intel_context *ce;
+
+   /*
+* Find the first VCS engine present. We're guaranteed there is one
+* if we're in this function due to the check in has_pxp
+*/
+   for (engine = gt->engine_class[VIDEO_DECODE_CLASS][0]; !engine; 
engine++);
+   GEM_BUG_ON(!engine || engine->class != VIDEO_DECODE_CLASS);
+
+   ce = intel_engine_create_pinned_context(engine, engine->gt->vm, SZ_4K,
+   I915_GEM_HWS_PXP_ADDR,
+   _lock, "pxp_context");
+   if (IS_ERR(ce)) {
+

[PATCH v7 00/17] drm/i915: Introduce Intel PXP

2021-08-27 Thread Daniele Ceraolo Spurio
PXP (Protected Xe Path) is an i915 component, available on
GEN12+, that helps to establish the hardware protected session
and manage the status of the alive software session, as well
as its life cycle.

Changes from v6:

- reworked object invalidation to be based on PXP instance instead of
  lists, so we can drop the locking (Daniel).

- just keep a wakeref while a protected context is around (Daniel).

- don't add a new flag to RESET_STATS, just increase the guilty count as
  if we had a hang (Daniel).

- add kerneldoc (Daniel). Added it all in one go at the end so it is
  easier to review.

- change location for the display blackscreen check (Juston).

- fix an issue with pxp component removal.

Tested with: https://patchwork.freedesktop.org/series/87570/

Cc: Gaurav Kumar 
Cc: Chris Wilson 
Cc: Rodrigo Vivi 
Cc: Joonas Lahtinen 
Cc: Juston Li 
Cc: Alan Previn 
Cc: Lionel Landwerlin 
Cc: Jason Ekstrand 
Cc: Daniel Vetter 

Anshuman Gupta (2):
  drm/i915/pxp: Add plane decryption support
  drm/i915/pxp: black pixels on pxp disabled

Daniele Ceraolo Spurio (9):
  drm/i915/pxp: Define PXP component interface
  drm/i915/pxp: define PXP device flag and kconfig
  drm/i915/pxp: allocate a vcs context for pxp usage
  drm/i915/pxp: set KCR reg init
  drm/i915/pxp: interfaces for using protected objects
  drm/i915/pxp: start the arb session on demand
  drm/i915/pxp: add pxp debugfs
  drm/i915/pxp: add PXP documentation
  drm/i915/pxp: enable PXP for integrated Gen12

Huang, Sean Z (5):
  drm/i915/pxp: Implement funcs to create the TEE channel
  drm/i915/pxp: Create the arbitrary session after boot
  drm/i915/pxp: Implement arb session teardown
  drm/i915/pxp: Implement PXP irq handler
  drm/i915/pxp: Enable PXP power management

Vitaly Lubart (1):
  mei: pxp: export pavp client to me client bus

 Documentation/gpu/i915.rst|   8 +
 drivers/gpu/drm/i915/Kconfig  |  11 +
 drivers/gpu/drm/i915/Makefile |  10 +
 drivers/gpu/drm/i915/display/intel_display.c  |  34 ++
 .../drm/i915/display/intel_display_types.h|   6 +
 .../drm/i915/display/skl_universal_plane.c|  49 ++-
 drivers/gpu/drm/i915/gem/i915_gem_context.c   | 100 +-
 drivers/gpu/drm/i915/gem/i915_gem_context.h   |   6 +
 .../gpu/drm/i915/gem/i915_gem_context_types.h |  28 ++
 drivers/gpu/drm/i915/gem/i915_gem_create.c|  72 +++--
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|  18 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.c|   1 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   6 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   8 +
 .../gpu/drm/i915/gem/selftests/mock_context.c |   4 +-
 drivers/gpu/drm/i915/gt/debugfs_gt.c  |   2 +
 drivers/gpu/drm/i915/gt/intel_engine.h|   2 +
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h  |  22 +-
 drivers/gpu/drm/i915/gt/intel_gt.c|   5 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c|   7 +
 drivers/gpu/drm/i915/gt/intel_gt_pm.c |  15 +-
 drivers/gpu/drm/i915/gt/intel_gt_types.h  |   3 +
 drivers/gpu/drm/i915/i915_drv.c   |   2 +
 drivers/gpu/drm/i915/i915_drv.h   |   3 +
 drivers/gpu/drm/i915/i915_pci.c   |   2 +
 drivers/gpu/drm/i915/i915_reg.h   |  48 +++
 drivers/gpu/drm/i915/intel_device_info.h  |   1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c  | 293 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.h  |  67 
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c  | 141 +
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h  |  15 +
 drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c  |  78 +
 drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.h  |  21 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c  | 100 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h  |  32 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c   |  40 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h   |  23 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 175 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h  |  15 +
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c  | 169 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h  |  17 +
 .../drm/i915/pxp/intel_pxp_tee_interface.h|  37 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h|  83 +
 drivers/misc/mei/Kconfig  |   2 +
 drivers/misc/mei/Makefile |   1 +
 drivers/misc/mei/pxp/Kconfig  |  13 +
 drivers/misc/mei/pxp/Makefile |   7 +
 drivers/misc/mei/pxp/mei_pxp.c| 229 ++
 drivers/misc/mei/pxp/mei_pxp.h|  18 ++
 include/drm/i915_component.h  |   1 +
 include/drm/i915_pxp_tee_interface.h  |  42 +++
 include/uapi/drm/i915_drm.h   |  58 +++-
 52 files changed, 2108 insertions(+), 42 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.h
 create mode 100644 

[PATCH v7 08/17] drm/i915/pxp: Implement arb session teardown

2021-08-27 Thread Daniele Ceraolo Spurio
From: "Huang, Sean Z" 

Teardown is triggered when the display topology changes and no
long meets the secure playback requirement, and hardware trashes
all the encryption keys for display. Additionally, we want to emit a
teardown operation to make sure we're clean on boot and resume

v2: emit in the ring, use high prio request (Chris)
v3: better defines, stalling flush, cleaned up and renamed submission
funcs (Chris)

Signed-off-by: Huang, Sean Z 
Signed-off-by: Daniele Ceraolo Spurio 
Cc: Chris Wilson 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/Makefile|   1 +
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h |  22 ++-
 drivers/gpu/drm/i915/pxp/intel_pxp.c |   7 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c | 141 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h |  15 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c |  29 
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
 7 files changed, 212 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 7e6bc5deb78f..3a12d5ff5402 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -283,6 +283,7 @@ i915-y += i915_perf.o
 # Protected execution platform (PXP) support
 i915-$(CONFIG_DRM_I915_PXP) += \
pxp/intel_pxp.o \
+   pxp/intel_pxp_cmd.o \
pxp/intel_pxp_session.o \
pxp/intel_pxp_tee.o
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h 
b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
index 1c3af0fc0456..ec2a0a566c40 100644
--- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
+++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
@@ -28,10 +28,13 @@
 #define INSTR_26_TO_24_MASK0x700
 #define   INSTR_26_TO_24_SHIFT 24
 
+#define __INSTR(client) ((client) << INSTR_CLIENT_SHIFT)
+
 /*
  * Memory interface instructions used by the kernel
  */
-#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
+#define MI_INSTR(opcode, flags) \
+   (__INSTR(INSTR_MI_CLIENT) | (opcode) << 23 | (flags))
 /* Many MI commands use bit 22 of the header dword for GGTT vs PPGTT */
 #define  MI_GLOBAL_GTT(1<<22)
 
@@ -57,6 +60,7 @@
 #define MI_SUSPEND_FLUSH   MI_INSTR(0x0b, 0)
 #define   MI_SUSPEND_FLUSH_EN  (1<<0)
 #define MI_SET_APPID   MI_INSTR(0x0e, 0)
+#define   MI_SET_APPID_SESSION_ID(x)   ((x) << 0)
 #define MI_OVERLAY_FLIPMI_INSTR(0x11, 0)
 #define   MI_OVERLAY_CONTINUE  (0x0<<21)
 #define   MI_OVERLAY_ON(0x1<<21)
@@ -146,6 +150,7 @@
 #define MI_STORE_REGISTER_MEM_GEN8   MI_INSTR(0x24, 2)
 #define   MI_SRM_LRM_GLOBAL_GTT(1<<22)
 #define MI_FLUSH_DWMI_INSTR(0x26, 1) /* for GEN6 */
+#define   MI_FLUSH_DW_PROTECTED_MEM_EN (1<<22)
 #define   MI_FLUSH_DW_STORE_INDEX  (1<<21)
 #define   MI_INVALIDATE_TLB(1<<18)
 #define   MI_FLUSH_DW_OP_STOREDW   (1<<14)
@@ -272,6 +277,19 @@
 #define   MI_MATH_REG_ZF   0x32
 #define   MI_MATH_REG_CF   0x33
 
+/*
+ * Media instructions used by the kernel
+ */
+#define MEDIA_INSTR(pipe, op, sub_op, flags) \
+   (__INSTR(INSTR_RC_CLIENT) | (pipe) << INSTR_SUBCLIENT_SHIFT | \
+   (op) << INSTR_26_TO_24_SHIFT | (sub_op) << 16 | (flags))
+
+#define MFX_WAIT   MEDIA_INSTR(1, 0, 0, 0)
+#define  MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAGREG_BIT(8)
+#define  MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAGREG_BIT(9)
+
+#define CRYPTO_KEY_EXCHANGEMEDIA_INSTR(2, 6, 9, 0)
+
 /*
  * Commands used only by the command parser
  */
@@ -328,8 +346,6 @@
 #define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_PS \
((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x47<<16))
 
-#define MFX_WAIT  ((0x3<<29)|(0x1<<27)|(0x0<<16))
-
 #define COLOR_BLT ((0x2<<29)|(0x40<<22))
 #define SRC_COPY_BLT  ((0x2<<29)|(0x43<<22))
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index e1370f323126..26176d43a02d 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -98,9 +98,14 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 
 void intel_pxp_init_hw(struct intel_pxp *pxp)
 {
+   int ret;
+
kcr_pxp_enable(pxp_to_gt(pxp));
 
-   intel_pxp_create_arb_session(pxp);
+   /* always emit a full termination to clean the state */
+   ret = intel_pxp_terminate_arb_session_and_global(pxp);
+   if (!ret)
+   intel_pxp_create_arb_session(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
new file mode 100644
index ..80678dafde15
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+

[PATCH v7 06/17] drm/i915/pxp: set KCR reg init

2021-08-27 Thread Daniele Ceraolo Spurio
The setting is required by hardware to allow us doing further protection
operation such as sending commands to GPU or TEE. The register needs to
be re-programmed on resume, so for simplicitly we bundle the programming
with the component binding, which is automatically called on resume.

Further HW set-up operations will be added in the same location in
follow-up patches, so get ready for them by using a couple of
init/fini_hw wrappers instead of calling the KCR funcs directly.

v3: move programming to component binding function, rework commit msg

Signed-off-by: Huang, Sean Z 
Signed-off-by: Daniele Ceraolo Spurio 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/pxp/intel_pxp.c | 27 
 drivers/gpu/drm/i915/pxp/intel_pxp.h |  3 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c |  5 +
 3 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 400deaea2d8a..66a98feb33ab 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -7,6 +7,24 @@
 #include "gt/intel_context.h"
 #include "i915_drv.h"
 
+/* KCR register definitions */
+#define KCR_INIT _MMIO(0x320f0)
+
+/* Setting KCR Init bit is required after system boot */
+#define KCR_INIT_ALLOW_DISPLAY_ME_WRITES REG_BIT(14)
+
+static void kcr_pxp_enable(struct intel_gt *gt)
+{
+   intel_uncore_write(gt->uncore, KCR_INIT,
+  
_MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
+}
+
+static void kcr_pxp_disable(struct intel_gt *gt)
+{
+   intel_uncore_write(gt->uncore, KCR_INIT,
+  
_MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
+}
+
 static int create_vcs_context(struct intel_pxp *pxp)
 {
static struct lock_class_key pxp_lock;
@@ -71,5 +89,14 @@ void intel_pxp_fini(struct intel_pxp *pxp)
intel_pxp_tee_component_fini(pxp);
 
destroy_vcs_context(pxp);
+}
+
+void intel_pxp_init_hw(struct intel_pxp *pxp)
+{
+   kcr_pxp_enable(pxp_to_gt(pxp));
+}
 
+void intel_pxp_fini_hw(struct intel_pxp *pxp)
+{
+   kcr_pxp_disable(pxp_to_gt(pxp));
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index e87550fb9821..5427c3b28aa9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -22,6 +22,9 @@ static inline bool intel_pxp_is_enabled(const struct 
intel_pxp *pxp)
 #ifdef CONFIG_DRM_I915_PXP
 void intel_pxp_init(struct intel_pxp *pxp);
 void intel_pxp_fini(struct intel_pxp *pxp);
+
+void intel_pxp_init_hw(struct intel_pxp *pxp);
+void intel_pxp_fini_hw(struct intel_pxp *pxp);
 #else
 static inline void intel_pxp_init(struct intel_pxp *pxp)
 {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 2f28f34c721d..46e788c9b30b 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -33,6 +33,9 @@ static int i915_pxp_tee_component_bind(struct device 
*i915_kdev,
pxp->pxp_component = data;
pxp->pxp_component->tee_dev = tee_kdev;
 
+   /* the component is required to fully start the PXP HW */
+   intel_pxp_init_hw(pxp);
+
return 0;
 }
 
@@ -41,6 +44,8 @@ static void i915_pxp_tee_component_unbind(struct device 
*i915_kdev,
 {
struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
 
+   intel_pxp_fini_hw(pxp);
+
pxp->pxp_component = NULL;
 }
 
-- 
2.25.1



[PATCH v7 10/17] drm/i915/pxp: interfaces for using protected objects

2021-08-27 Thread Daniele Ceraolo Spurio
This api allow user mode to create protected buffers and to mark
contexts as making use of such objects. Only when using contexts
marked in such a way is the execution guaranteed to work as expected.

Contexts can only be marked as using protected content at creation time
(i.e. the parameter is immutable) and they must be both bannable and not
recoverable. Given that the protected session gets invalidated on
suspend, contexts created this way hold a runtime pm wakeref until
they're either destroyed or invalidated.

All protected objects and contexts will be considered invalid when the
PXP session is destroyed and all new submissions using them will be
rejected. All intel contexts within the invalidated gem contexts will be
marked banned. Userspace can detect that an invalidation has occurred via
the RESET_STATS ioctl, where we report it the same way as a ban due to a
hang.

v5: squash patches, rebase on proto_ctx, update kerneldoc

v6: rebase on obj create_ext changes

v7: Use session counter to check if an object it valid, hold wakeref in
context, don't add a new flag to RESET_STATS (Daniel)

Signed-off-by: Daniele Ceraolo Spurio 
Signed-off-by: Bommu Krishnaiah 
Cc: Rodrigo Vivi 
Cc: Chris Wilson 
Cc: Lionel Landwerlin 
Cc: Jason Ekstrand 
Cc: Daniel Vetter 
Reviewed-by: Rodrigo Vivi  #v5
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c   | 98 ---
 drivers/gpu/drm/i915/gem/i915_gem_context.h   |  6 ++
 .../gpu/drm/i915/gem/i915_gem_context_types.h | 28 ++
 drivers/gpu/drm/i915/gem/i915_gem_create.c| 72 ++
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 18 
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  1 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|  6 ++
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  8 ++
 .../gpu/drm/i915/gem/selftests/mock_context.c |  4 +-
 drivers/gpu/drm/i915/pxp/intel_pxp.c  | 83 
 drivers/gpu/drm/i915/pxp/intel_pxp.h  | 12 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  6 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h|  9 ++
 include/uapi/drm/i915_drm.h   | 55 ++-
 14 files changed, 371 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index fd169cf2f75a..f411e26768fd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -77,6 +77,8 @@
 #include "gt/intel_gpu_commands.h"
 #include "gt/intel_ring.h"
 
+#include "pxp/intel_pxp.h"
+
 #include "i915_gem_context.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
@@ -186,10 +188,13 @@ static int validate_priority(struct drm_i915_private 
*i915,
return 0;
 }
 
-static void proto_context_close(struct i915_gem_proto_context *pc)
+static void proto_context_close(struct drm_i915_private *i915,
+   struct i915_gem_proto_context *pc)
 {
int i;
 
+   if (pc->pxp_wakeref)
+   intel_runtime_pm_put(>runtime_pm, pc->pxp_wakeref);
if (pc->vm)
i915_vm_put(pc->vm);
if (pc->user_engines) {
@@ -241,6 +246,33 @@ static int proto_context_set_persistence(struct 
drm_i915_private *i915,
return 0;
 }
 
+static int proto_context_set_protected(struct drm_i915_private *i915,
+  struct i915_gem_proto_context *pc,
+  bool protected)
+{
+   int ret = 0;
+
+   if (!intel_pxp_is_enabled(>gt.pxp)) {
+   ret = -ENODEV;
+   } else if (!protected) {
+   pc->uses_protected_content = false;
+   } else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
+  !(pc->user_flags & BIT(UCONTEXT_BANNABLE))) {
+   ret = -EPERM;
+   } else {
+   pc->uses_protected_content = true;
+
+   /*
+* protected context usage requires the PXP session to be up,
+* which in turn requires the device to be active.
+*/
+   pc->pxp_wakeref = intel_runtime_pm_get(>runtime_pm);
+   ret = intel_pxp_wait_for_arb_start(>gt.pxp);
+   }
+
+   return ret;
+}
+
 static struct i915_gem_proto_context *
 proto_context_create(struct drm_i915_private *i915, unsigned int flags)
 {
@@ -269,7 +301,7 @@ proto_context_create(struct drm_i915_private *i915, 
unsigned int flags)
return pc;
 
 proto_close:
-   proto_context_close(pc);
+   proto_context_close(i915, pc);
return err;
 }
 
@@ -693,6 +725,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private 
*fpriv,
ret = -EPERM;
else if (args->value)
pc->user_flags |= BIT(UCONTEXT_BANNABLE);
+   else if (pc->uses_protected_content)
+   ret = -EPERM;
else
pc->user_flags &= 

[PATCH v7 03/17] drm/i915/pxp: define PXP device flag and kconfig

2021-08-27 Thread Daniele Ceraolo Spurio
Ahead of the PXP implementation, define the relevant define flag and
kconfig option.

v2: flip kconfig default to N. Some machines have IFWIs that do not
support PXP, so we need it to be an opt-in until we add support to query
the caps from the mei device.

Signed-off-by: Daniele Ceraolo Spurio 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/Kconfig | 11 +++
 drivers/gpu/drm/i915/i915_drv.h  |  3 +++
 drivers/gpu/drm/i915/intel_device_info.h |  1 +
 3 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index f960f5d7664e..5987c3d5d9fb 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -131,6 +131,17 @@ config DRM_I915_GVT_KVMGT
  Choose this option if you want to enable KVMGT support for
  Intel GVT-g.
 
+config DRM_I915_PXP
+   bool "Enable Intel PXP support for Intel Gen12+ platform"
+   depends on DRM_I915
+   depends on INTEL_MEI && INTEL_MEI_PXP
+   default n
+   help
+ PXP (Protected Xe Path) is an i915 component, available on GEN12+
+ GPUs, that helps to establish the hardware protected session and
+ manage the status of the alive software session, as well as its life
+ cycle.
+
 menu "drm/i915 Debugging"
 depends on DRM_I915
 depends on EXPERT
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f64ba566fe8c..1b351f0267cb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1701,6 +1701,9 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define HAS_GLOBAL_MOCS_REGISTERS(dev_priv)
(INTEL_INFO(dev_priv)->has_global_mocs)
 
+#define HAS_PXP(dev_priv) (IS_ENABLED(CONFIG_DRM_I915_PXP) && \
+  INTEL_INFO(dev_priv)->has_pxp) && \
+  VDBOX_MASK(_priv->gt)
 
 #define HAS_GMCH(dev_priv) (INTEL_INFO(dev_priv)->display.has_gmch)
 
diff --git a/drivers/gpu/drm/i915/intel_device_info.h 
b/drivers/gpu/drm/i915/intel_device_info.h
index d328bb95c49b..8e6f48d1eb7b 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -133,6 +133,7 @@ enum intel_ppgtt_type {
func(has_logical_ring_elsq); \
func(has_mslices); \
func(has_pooled_eu); \
+   func(has_pxp); \
func(has_rc6); \
func(has_rc6p); \
func(has_rps); \
-- 
2.25.1



[PATCH v7 02/17] mei: pxp: export pavp client to me client bus

2021-08-27 Thread Daniele Ceraolo Spurio
From: Vitaly Lubart 

Export PAVP client to work with i915 driver,
for binding it uses kernel component framework.

v2:drop debug prints, refactor match code to match mei_hdcp (Tomas)

Signed-off-by: Vitaly Lubart 
Signed-off-by: Tomas Winkler 
Signed-off-by: Daniele Ceraolo Spurio 
Reviewed-by: Rodrigo Vivi  #v1
---
 drivers/misc/mei/Kconfig   |   2 +
 drivers/misc/mei/Makefile  |   1 +
 drivers/misc/mei/pxp/Kconfig   |  13 ++
 drivers/misc/mei/pxp/Makefile  |   7 +
 drivers/misc/mei/pxp/mei_pxp.c | 229 +
 drivers/misc/mei/pxp/mei_pxp.h |  18 +++
 6 files changed, 270 insertions(+)
 create mode 100644 drivers/misc/mei/pxp/Kconfig
 create mode 100644 drivers/misc/mei/pxp/Makefile
 create mode 100644 drivers/misc/mei/pxp/mei_pxp.c
 create mode 100644 drivers/misc/mei/pxp/mei_pxp.h

diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index f5fd5b786607..0e0bcd0da852 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -47,3 +47,5 @@ config INTEL_MEI_TXE
  Intel Bay Trail
 
 source "drivers/misc/mei/hdcp/Kconfig"
+source "drivers/misc/mei/pxp/Kconfig"
+
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index f1c76f7ee804..d8e5165917f2 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -26,3 +26,4 @@ mei-$(CONFIG_EVENT_TRACING) += mei-trace.o
 CFLAGS_mei-trace.o = -I$(src)
 
 obj-$(CONFIG_INTEL_MEI_HDCP) += hdcp/
+obj-$(CONFIG_INTEL_MEI_PXP) += pxp/
diff --git a/drivers/misc/mei/pxp/Kconfig b/drivers/misc/mei/pxp/Kconfig
new file mode 100644
index ..4029b96afc04
--- /dev/null
+++ b/drivers/misc/mei/pxp/Kconfig
@@ -0,0 +1,13 @@
+
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2020, Intel Corporation. All rights reserved.
+#
+config INTEL_MEI_PXP
+   tristate "Intel PXP services of ME Interface"
+   select INTEL_MEI_ME
+   depends on DRM_I915
+   help
+ MEI Support for PXP Services on Intel platforms.
+
+ Enables the ME FW services required for PXP support through
+ I915 display driver of Intel.
diff --git a/drivers/misc/mei/pxp/Makefile b/drivers/misc/mei/pxp/Makefile
new file mode 100644
index ..0329950d5794
--- /dev/null
+++ b/drivers/misc/mei/pxp/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.
+#
+# Makefile - PXP client driver for Intel MEI Bus Driver.
+
+obj-$(CONFIG_INTEL_MEI_PXP) += mei_pxp.o
diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c
new file mode 100644
index ..f7380d387bab
--- /dev/null
+++ b/drivers/misc/mei/pxp/mei_pxp.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright © 2020 - 2021 Intel Corporation
+ */
+
+/**
+ * DOC: MEI_PXP Client Driver
+ *
+ * The mei_pxp driver acts as a translation layer between PXP
+ * protocol  implementer (I915) and ME FW by translating PXP
+ * negotiation messages to ME FW command payloads and vice versa.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mei_pxp.h"
+
+/**
+ * mei_pxp_send_message() - Sends a PXP message to ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @message: a message buffer to send
+ * @size: size of the message
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_pxp_send_message(struct device *dev, const void *message, size_t size)
+{
+   struct mei_cl_device *cldev;
+   ssize_t byte;
+
+   if (!dev || !message)
+   return -EINVAL;
+
+   cldev = to_mei_cl_device(dev);
+
+   /* temporary drop const qualifier till the API is fixed */
+   byte = mei_cldev_send(cldev, (u8 *)message, size);
+   if (byte < 0) {
+   dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+   return byte;
+   }
+
+   return 0;
+}
+
+/**
+ * mei_pxp_receive_message() - Receives a PXP message from ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @buffer: a message buffer to contain the received message
+ * @size: size of the buffer
+ * Return: bytes sent on Success, <0 on Failure
+ */
+static int
+mei_pxp_receive_message(struct device *dev, void *buffer, size_t size)
+{
+   struct mei_cl_device *cldev;
+   ssize_t byte;
+
+   if (!dev || !buffer)
+   return -EINVAL;
+
+   cldev = to_mei_cl_device(dev);
+
+   byte = mei_cldev_recv(cldev, buffer, size);
+   if (byte < 0) {
+   dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+   return byte;
+   }
+
+   return byte;
+}
+
+static const struct i915_pxp_component_ops mei_pxp_ops = {
+   .owner = THIS_MODULE,
+   .send = mei_pxp_send_message,
+   .recv = mei_pxp_receive_message,
+};
+
+static int mei_component_master_bind(struct device *dev)
+{
+   struct mei_cl_device *cldev = to_mei_cl_device(dev);
+   struct i915_pxp_component *comp_master = 

[PATCH 2/2] drm/amdgpu: Example Usage in AMDGPU

2021-08-27 Thread Fangzhi Zuo
1. Decide MST Link Encoding Cap
2. Update MST First Link Slot Information

Signed-off-by: Fangzhi Zuo 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  4 +++-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c| 10 ++
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h|  2 ++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 986c9d29d686..90edf0eae786 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2302,6 +2302,7 @@ static int dm_resume(void *handle)
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
amdgpu_dm_update_connector_after_detect(aconnector);
+   get_mst_link_encoding_cap(aconnector);
mutex_unlock(>hpd_lock);
}
drm_connector_list_iter_end();
@@ -2673,6 +2674,7 @@ static void handle_hpd_irq(void *param)
if (aconnector->base.force == DRM_FORCE_UNSPECIFIED)
drm_kms_helper_hotplug_event(dev);
}
+   get_mst_link_encoding_cap(aconnector);
mutex_unlock(>hpd_lock);
 
 }
@@ -3844,7 +3846,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
amdgpu_dm_set_psr_caps(link);
}
 
-
+   get_mst_link_encoding_cap(aconnector);
}
 
/* Software is initialized. Now we can register interrupt handlers. */
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 5568d4e518e6..2f029cbdd3f8 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
@@ -439,6 +439,16 @@ static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
.add_connector = dm_dp_add_mst_connector,
 };
 
+void get_mst_link_encoding_cap(struct amdgpu_dm_connector *aconnector)
+{
+   u8 link_encoding_cap;
+
+   if (aconnector->dc_link->type == dc_connection_mst_branch) {
+   link_encoding_cap = 
dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
+   drm_dp_mst_update_coding_cap(>mst_mgr, 
link_encoding_cap);
+   }
+}
+
 void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
   struct amdgpu_dm_connector *aconnector,
   int link_index)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
index b38bd68121ce..8339053b2b70 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
@@ -35,6 +35,8 @@ void amdgpu_dm_initialize_dp_connector(struct 
amdgpu_display_manager *dm,
   struct amdgpu_dm_connector *aconnector,
   int link_index);
 
+void get_mst_link_encoding_cap(struct amdgpu_dm_connector *aconnector);
+
 void
 dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev);
 
-- 
2.25.1



[PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format

2021-08-27 Thread Fangzhi Zuo
8b/10b encoding format requires to reserve the first slot for
recording metadata. Real data transmission starts from the second slot,
with a total of available 63 slots available.

In 128b/132b encoding format, metadata is transmitted separately
in LLCP packet before MTP. Real data transmission starts from
the first slot, with a total of 64 slots available.

Signed-off-by: Fangzhi Zuo 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 27 ---
 include/drm/drm_dp_mst_helper.h   |  9 +
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 86d13d6bc463..30544801d2b8 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3370,7 +3370,7 @@ int drm_dp_update_payload_part1(struct 
drm_dp_mst_topology_mgr *mgr)
struct drm_dp_payload req_payload;
struct drm_dp_mst_port *port;
int i, j;
-   int cur_slots = 1;
+   int cur_slots = mgr->start_slot;
bool skip;
 
mutex_lock(>payload_lock);
@@ -4323,7 +4323,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr 
*mgr,
num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
 
/* max. time slots - one slot for MTP header */
-   if (num_slots > 63)
+   if (num_slots > mgr->total_avail_slots)
return -ENOSPC;
return num_slots;
 }
@@ -4335,7 +4335,7 @@ static int drm_dp_init_vcpi(struct 
drm_dp_mst_topology_mgr *mgr,
int ret;
 
/* max. time slots - one slot for MTP header */
-   if (slots > 63)
+   if (slots > mgr->total_avail_slots)
return -ENOSPC;
 
vcpi->pbn = pbn;
@@ -4509,6 +4509,17 @@ int drm_dp_atomic_release_vcpi_slots(struct 
drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 
+void drm_dp_mst_update_encoding_cap(struct drm_dp_mst_topology_mgr *mgr, 
uint8_t link_encoding_cap)
+{
+   if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
+   mgr->total_avail_slots = 64;
+   mgr->start_slot = 0;
+   }
+   DRM_DEBUG_KMS("%s encoding format determined\n",
+ (link_encoding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b" 
: "8b/10b");
+}
+EXPORT_SYMBOL(drm_dp_mst_update_encoding_cap);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -4540,8 +4551,8 @@ bool drm_dp_mst_allocate_vcpi(struct 
drm_dp_mst_topology_mgr *mgr,
 
ret = drm_dp_init_vcpi(mgr, >vcpi, pbn, slots);
if (ret) {
-   drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63 
ret=%d\n",
-   DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
+   drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=%d 
ret=%d\n",
+   DIV_ROUND_UP(pbn, mgr->pbn_div), 
mgr->total_avail_slots, ret);
drm_dp_mst_topology_put_port(port);
goto out;
}
@@ -5228,7 +5239,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct 
drm_dp_mst_topology_mgr *mgr,
 struct drm_dp_mst_topology_state 
*mst_state)
 {
struct drm_dp_vcpi_allocation *vcpi;
-   int avail_slots = 63, payload_count = 0;
+   int avail_slots = mgr->total_avail_slots, payload_count = 0;
 
list_for_each_entry(vcpi, _state->vcpis, next) {
/* Releasing VCPI is always OK-even if the port is gone */
@@ -5257,7 +5268,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct 
drm_dp_mst_topology_mgr *mgr,
}
}
drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d 
used=%d\n",
-  mgr, mst_state, avail_slots, 63 - avail_slots);
+  mgr, mst_state, avail_slots, mgr->total_avail_slots - 
avail_slots);
 
return 0;
 }
@@ -5529,6 +5540,8 @@ int drm_dp_mst_topology_mgr_init(struct 
drm_dp_mst_topology_mgr *mgr,
if (!mgr->proposed_vcpis)
return -ENOMEM;
set_bit(0, >payload_mask);
+   mgr->total_avail_slots = 63;
+   mgr->start_slot = 1;
 
mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
if (mst_state == NULL)
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index ddb9231d0309..eac5ce48f214 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -661,6 +661,15 @@ struct drm_dp_mst_topology_mgr {
 */
int pbn_div;
 
+   /**
+* @total_avail_slots: available slots for data transmission
+*/
+   u8 total_avail_slots;
+   /**
+* @start_slot: first slot index for data transmission
+*/
+   u8 start_slot;
+
/**
 * @funcs: Atomic helper callbacks
 */
-- 
2.25.1



[PATCH 0/2] Update 128b/132b MST Slot Information

2021-08-27 Thread Fangzhi Zuo
128b/132b MST start slot information is not the same as 8b/10b.
Update based on encoding format after link detection or topology change.

Fangzhi Zuo (2):
  drm: Update MST First Link Slot Information Based on Encoding Format
  drm/amdgpu: Example Usage in AMDGPU

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  4 ++-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 10 +++
 .../display/amdgpu_dm/amdgpu_dm_mst_types.h   |  2 ++
 drivers/gpu/drm/drm_dp_mst_topology.c | 27 ++-
 include/drm/drm_dp_mst_helper.h   |  9 +++
 5 files changed, 44 insertions(+), 8 deletions(-)

-- 
2.25.1



Re: drm: simpledrm: fbdev emulation error with CONFIG_DRM_SIMPLEDRM enabled

2021-08-27 Thread Amanoel Dawod
Hi

On Thu, Aug 26, 2021, at 2:31 PM, Thomas Zimmermann wrote:
> 
> You said that the resolution is 3840 x 2160, but the attached log says 
> 1024x768. I guess that the former is the monitor's native resolution and 
> the latter is the display mode?
> 

Yes, that's the monitor native resolution and what I was running within Gnome
shell, but I believe since I'm now booting to text mode with only simpledrm
it reports 1024x768.

> The attached patch adds a few extra lines of debugging output. Could you 
> please apply it, rebuild, and report back with the log.
> 
> Best regards
> Thomas
> 

Sure, I applied the patch. Please find new dmesg output attached.

-- 
thanks,
Amanoel[2.441587] [drm:0xc03670cc] Initialized
[2.447368] simple-framebuffer simple-framebuffer.0: 
[drm:0xc03af69d] display mode={"1024x768": 6 47185920 1024 1024 
1024 1024 768 768 768 768 0x40 0x0}
[2.447371] simple-framebuffer simple-framebuffer.0: 
[drm:0xc03af6c0] framebuffer format=AR24 little-endian (0x34325241), 
size=1024x768, stride=4096 byte
[2.447388] [drm:0xc0303ccb] 
[2.447389] [drm:0xc0303e94] 
[2.447413] [drm:0xc0303ef8] new minor registered 0
[2.447420] [drm:0xc0304c48] adding "Unknown-1" to sysfs
[2.447421] [drm:0xc0304aea] generating hotplug event
[2.447423] [drm] Initialized simpledrm 1.0.0 20200625 for 
simple-framebuffer.0 on minor 0
[2.447424] [drm:0xc0331399] 
[2.447425] [drm:0xc03200d1] OBJ ID: 31 (2)
[2.447426] [drm:0xc0380260] [CONNECTOR:31:Unknown-1]
[2.447427] [drm:0xc0380334] [CONNECTOR:31:Unknown-1] status updated 
from unknown to connected
[2.447430] [drm:0xc03805c5] [CONNECTOR:31:Unknown-1] probed modes :
[2.447431] [drm:0xc0308be3] Modeline "1024x768": 6 47185920 
1024 1024 1024 1024 768 768 768 768 0x48 0x0
[2.447432] [drm:0xc0331613] connector 31 enabled? yes
[2.447433] [drm:0xc03319dd] Not using firmware configuration
[2.447434] [drm:0xc0331c49] looking for cmdline mode on connector 31
[2.447434] [drm:0xc0332131] looking for preferred mode on connector 
31 0
[2.447435] [drm:0xc0331d43] found mode 1024x768
[2.447435] [drm:0xc0331f1f] picking CRTCs for 1024x768 config
[2.447436] [drm:0xc033206b] desired mode 1024x768 set on crtc 34 
(0,0)
[2.447436] [drm:0xc03200d1] OBJ ID: 31 (2)
[2.447437] [drm:0xc0320181] OBJ ID: 31 (3)
[2.447437] simple-framebuffer simple-framebuffer.0: 
[drm:0xc0394dc7] test CRTC 0 primary plane
[2.447438] [drm:0xc0394ec4] *ERROR* x=0 y=0, 
desired_mode->hdisplay=1024 desired_mode->vdisplay=1024 sizes.surface_width=768 
sizes.surface_height=768
[2.447439] [drm:0xc0394f03] *ERROR* connector->has_tile=0
[2.447440] simple-framebuffer simple-framebuffer.0: 
[drm:0xc0397cba] surface width(1024), height(2304) and bpp(32)
[2.447443] [drm:0xc031b483] bad framebuffer height 2304, should be 
>= 768 && <= 768
[2.447445] simple-framebuffer simple-framebuffer.0: [drm] *ERROR* fbdev: 
Failed to setup generic emulation (ret=-22)
[2.447446] simple-framebuffer simple-framebuffer.0: 
[drm:0xc03968de] client hotplug ret=-22
[   14.629995] systemd[1]: Starting Load Kernel Module drm...
[   14.634356] systemd[1]: modprobe@drm.service: Deactivated successfully.
[   14.634421] systemd[1]: Finished Load Kernel Module drm.


Re: [RFC PATCH 0/4] Allow to use DRM fbdev emulation layer with CONFIG_FB disabled

2021-08-27 Thread Javier Martinez Canillas
Hello Daniel and Thomas,

On 8/27/21 10:20 PM, Daniel Vetter wrote:
> On Fri, Aug 27, 2021 at 07:50:23PM +0200, Thomas Zimmermann wrote:
>> Hi
>>
>> Am 27.08.21 um 12:00 schrieb Javier Martinez Canillas:
>>> This patch series splits the fbdev core support in two different Kconfig
>>> symbols: FB and FB_CORE. The motivation for this is to allow CONFIG_FB to
>>> be disabled, while still using fbcon with the DRM fbdev emulation layer.
>>
>> I'm skeptical. DRM's fbdev emulation is not just the console emulation, it's
>> a full fbdev device. You can see the related device file as /dev/fb*.
>> Providing the file while having CONFIG_FB disabled doesn't make much sense
>> to me. I know it's not pretty, but it's consistent at least.
>>
>> If you want to remove fbdev, you could try to untangle fbdev and the console
>> emulation such that DRM can set up a console by itself. Old fbdev drives
>> would also set up the console individually.
> 
> Yeah given the horrendous security track record of all that code, and the
> maze of handover we have (stuff like flicker free boot and all that) I'm
> wondering whether typing a new drmcon wouldn't be faster and a lot more
> maintainable.
> 

We talked about a drmcon with Peter Robinson as well but then decided that a
way to disable CONFIG_FB but still having the DRM fbdev emulation could be a
intermediary step, hence these RFC patches.

But yes, I agree that a drmcon would be the proper approach for this, to not
need any fbdev support at all. We will just keep the explicit disable for the
fbdev drivers then in the meantime.

Thanks a lot for your feedback.

Best regards,
-- 
Javier Martinez Canillas
Linux Engineering
Red Hat



[Bug 211807] [drm:drm_dp_mst_dpcd_read] *ERROR* mstb 000000004e6288dd port 3: DPCD read on addr 0x60 for 1 bytes NAKed

2021-08-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=211807

Nils Tonnätt (nils.tonna...@posteo.de) changed:

   What|Removed |Added

 CC||nils.tonna...@posteo.de

--- Comment #3 from Nils Tonnätt (nils.tonna...@posteo.de) ---
Same with Radeon RX5500 and Dell P2815Q display.

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

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

Re: [RFC] drm/msm/dp: Allow attaching a drm_panel

2021-08-27 Thread Doug Anderson
Hi,

On Mon, Jul 26, 2021 at 4:15 PM Bjorn Andersson
 wrote:
>
> +static int dp_parser_find_panel(struct dp_parser *parser)
> +{
> +   struct device_node *np = parser->pdev->dev.of_node;
> +   int rc;
> +
> +   rc = drm_of_find_panel_or_bridge(np, 2, 0, >drm_panel, NULL);

Why port 2? Shouldn't this just be port 1 always? The yaml says that
port 1 is "Output endpoint of the controller". We should just use port
1 here, right?

-Doug


[PATCH v3 3/4] drm/amdgpu: drm/amdgpu: Handle IOMMU enabled case

2021-08-27 Thread Andrey Grodzovsky
Handle all DMA IOMMU group related dependencies before the
group is removed and we try to access it after free.

v2:
Move the actul handling function to TTM

Signed-off-by: Andrey Grodzovsky 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 0b5764aa98a4..653bd8fdaa33 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3860,6 +3860,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
 
amdgpu_device_ip_fini_early(adev);
 
+   ttm_device_clear_dma_mappings(>mman.bdev);
+
amdgpu_gart_dummy_page_fini(adev);
 
amdgpu_device_unmap_mmio(adev);
-- 
2.25.1



[PATCH v3 4/4] drm/amdgpu: Add a UAPI flag for hot plug/unplug

2021-08-27 Thread Andrey Grodzovsky
To support libdrm tests.

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

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 6400259a7c4b..c2fdf67ff551 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -96,9 +96,10 @@
  * - 3.40.0 - Add AMDGPU_IDS_FLAGS_TMZ
  * - 3.41.0 - Add video codec query
  * - 3.42.0 - Add 16bpc fixed point display support
+ * - 3.43.0 - Add device hot plug/unplug support
  */
 #define KMS_DRIVER_MAJOR   3
-#define KMS_DRIVER_MINOR   42
+#define KMS_DRIVER_MINOR   43
 #define KMS_DRIVER_PATCHLEVEL  0
 
 int amdgpu_vram_limit;
-- 
2.25.1



[PATCH v3 2/4] drm/ttm: Clear all DMA mappings on demand

2021-08-27 Thread Andrey Grodzovsky
Used by drivers supporting hot unplug to handle all
DMA IOMMU group related dependencies before the group
is removed during device removal and we try to access
it after free when last device pointer from user space
is dropped.

v3:
Switch to ttm_bo_get_unless_zerom
Iterate bdev for pinned list
Switch to ttm_tt_unpopulate

Signed-off-by: Andrey Grodzovsky 
---
 drivers/gpu/drm/ttm/ttm_device.c | 47 
 include/drm/ttm/ttm_device.h |  1 +
 2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index 530a9c36be37..a691c89f5b20 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -246,3 +246,50 @@ void ttm_device_fini(struct ttm_device *bdev)
ttm_global_release();
 }
 EXPORT_SYMBOL(ttm_device_fini);
+
+void ttm_device_clear_dma_mappings(struct ttm_device *bdev)
+{
+   struct ttm_resource_manager *man;
+   struct ttm_buffer_object *bo;
+   unsigned int i, j;
+
+   spin_lock(>lru_lock);
+   while (!list_empty(>pinned)) {
+   bo = list_first_entry(>pinned, struct ttm_buffer_object, 
lru);
+   /* Take ref against racing releases once lru_lock is unlocked */
+   if (ttm_bo_get_unless_zero(bo)) {
+   list_del_init(>lru);
+   spin_unlock(>lru_lock);
+
+   if (bo->ttm)
+   ttm_tt_unpopulate(bo->bdev, bo->ttm);
+
+   ttm_bo_put(bo);
+   spin_lock(>lru_lock);
+   }
+   }
+
+   for (i = TTM_PL_SYSTEM; i < TTM_NUM_MEM_TYPES; ++i) {
+   man = ttm_manager_type(bdev, i);
+   if (!man || !man->use_tt)
+   continue;
+
+   for (j = 0; j < TTM_MAX_BO_PRIORITY; ++j) {
+   while (!list_empty(>lru[j])) {
+   bo = list_first_entry(>lru[j], struct 
ttm_buffer_object, lru);
+   if (ttm_bo_get_unless_zero(bo)) {
+   list_del_init(>lru);
+   spin_unlock(>lru_lock);
+
+   if (bo->ttm)
+   ttm_tt_unpopulate(bo->bdev, 
bo->ttm);
+
+   ttm_bo_put(bo);
+   spin_lock(>lru_lock);
+   }
+   }
+   }
+   }
+   spin_unlock(>lru_lock);
+}
+EXPORT_SYMBOL(ttm_device_clear_dma_mappings);
diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h
index 03fb44d061e0..07d722950d5b 100644
--- a/include/drm/ttm/ttm_device.h
+++ b/include/drm/ttm/ttm_device.h
@@ -299,5 +299,6 @@ int ttm_device_init(struct ttm_device *bdev, struct 
ttm_device_funcs *funcs,
struct drm_vma_offset_manager *vma_manager,
bool use_dma_alloc, bool use_dma32);
 void ttm_device_fini(struct ttm_device *bdev);
+void ttm_device_clear_dma_mappings(struct ttm_device *bdev);
 
 #endif
-- 
2.25.1



[PATCH v3 1/4] drm/ttm: Create pinned list

2021-08-27 Thread Andrey Grodzovsky
This list will be used to capture all non VRAM BOs not
on LRU so when device is hot unplugged we can iterate
the list and unmap DMA mappings before device is removed.

v2: Reanme function to ttm_bo_move_to_pinned
v3: Move the pinned list to ttm device

Signed-off-by: Andrey Grodzovsky 
Suggested-by: Christian König 
---
 drivers/gpu/drm/ttm/ttm_bo.c | 18 ++
 drivers/gpu/drm/ttm/ttm_device.c |  1 +
 include/drm/ttm/ttm_device.h |  1 +
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 1b950b45cf4b..1fedd0eb67ba 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -69,7 +69,17 @@ static void ttm_bo_mem_space_debug(struct ttm_buffer_object 
*bo,
}
 }
 
-static void ttm_bo_del_from_lru(struct ttm_buffer_object *bo)
+static inline void ttm_bo_move_to_pinned(struct ttm_buffer_object *bo)
+{
+   struct ttm_device *bdev = bo->bdev;
+
+   list_move_tail(>lru, >pinned);
+
+   if (bdev->funcs->del_from_lru_notify)
+   bdev->funcs->del_from_lru_notify(bo);
+}
+
+static inline void ttm_bo_del_from_lru(struct ttm_buffer_object *bo)
 {
struct ttm_device *bdev = bo->bdev;
 
@@ -98,7 +108,7 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo,
dma_resv_assert_held(bo->base.resv);
 
if (bo->pin_count) {
-   ttm_bo_del_from_lru(bo);
+   ttm_bo_move_to_pinned(bo);
return;
}
 
@@ -339,7 +349,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo,
return ret;
}
 
-   ttm_bo_del_from_lru(bo);
+   ttm_bo_move_to_pinned(bo);
list_del_init(>ddestroy);
spin_unlock(>bdev->lru_lock);
ttm_bo_cleanup_memtype_use(bo);
@@ -1154,7 +1164,7 @@ int ttm_bo_swapout(struct ttm_buffer_object *bo, struct 
ttm_operation_ctx *ctx,
return 0;
}
 
-   ttm_bo_del_from_lru(bo);
+   ttm_bo_move_to_pinned(bo);
/* TODO: Cleanup the locking */
spin_unlock(>bdev->lru_lock);
 
diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index 5f31acec3ad7..530a9c36be37 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -208,6 +208,7 @@ int ttm_device_init(struct ttm_device *bdev, struct 
ttm_device_funcs *funcs,
INIT_DELAYED_WORK(>wq, ttm_device_delayed_workqueue);
spin_lock_init(>lru_lock);
INIT_LIST_HEAD(>ddestroy);
+   INIT_LIST_HEAD(>pinned);
bdev->dev_mapping = mapping;
mutex_lock(_global_mutex);
list_add_tail(>device_list, >device_list);
diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h
index cd592f8e941b..03fb44d061e0 100644
--- a/include/drm/ttm/ttm_device.h
+++ b/include/drm/ttm/ttm_device.h
@@ -265,6 +265,7 @@ struct ttm_device {
 */
spinlock_t lru_lock;
struct list_head ddestroy;
+   struct list_head pinned;
 
/*
 * Protected by load / firstopen / lastclose /unload sync.
-- 
2.25.1



[PATCH v3 0/4] Various fixes to pass libdrm hotunplug tests

2021-08-27 Thread Andrey Grodzovsky
Bunch of fixes to enable passing hotplug tests i previosly added
here[1] with latest code. 
Once accepted I will enable the tests on libdrm side.

[1] - https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/172

v2:
Dropping VCE patch since relevant function already fixed in latest
code.
Moving IOMMU hnadling to TTM layer.

v3:
Move pinned list to ttm device and a few others.

Andrey Grodzovsky (4):
  drm/ttm: Create pinned list
  drm/ttm: Clear all DMA mappings on demand
  drm/amdgpu: drm/amdgpu: Handle IOMMU enabled case
  drm/amdgpu: Add a UAPI flag for hot plug/unplug

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c|  3 +-
 drivers/gpu/drm/ttm/ttm_bo.c   | 18 ++--
 drivers/gpu/drm/ttm/ttm_device.c   | 48 ++
 include/drm/ttm/ttm_device.h   |  2 +
 5 files changed, 68 insertions(+), 5 deletions(-)

-- 
2.25.1



Re: [PATCH 1/2] dma-buf: nuke DMA_FENCE_TRACE macros v2

2021-08-27 Thread Daniel Vetter
On Fri, Aug 27, 2021 at 11:07:58AM +0200, Christian König wrote:
> Am 26.08.21 um 10:55 schrieb Daniel Vetter:
> > On Tue, Aug 24, 2021 at 10:12:24AM +0200, Christian König wrote:
> > > Just a gentle ping. Daniel any more comments on this?
> > Still haven't seen a patch set to nuke the sw_sync igt tests. Otherwise
> > this is just going to cause fails and reboots in our ci (we reboot on
> > taints).
> 
> *sigh* can I at least print a warning without breaking the igt tests?

CI watches dmesg too ... it just doesn't force a reboot (which hurts run
rate really badly).

> > > I'm not sure if the second patch will cause trouble with any unit test, 
> > > but
> > > I'm willing to try it. We can always trivial revert it.
> > See above, remove the igts and we should be fine I think. I don't think
> > there's any selftests or kselftests, but checking that should be a quick
> > grep at most.
> 
> Yeah, we don't have any selftests as far as I can see but this stuff is so
> interweaved with igt that it will be hard to remove I think.
> 
> A good bunch of the igt code seems to have been moved to using VGEM instead,
> but as far as I can see there is still plenty left relying on this.
> 
> Alternatively could we make the config option depend on CONFIG_DEBUG?

Hm I thought it was just down to sw_sync igt testcase, and everything else
is moved to vgem. Do we have more, or has more landed since I looked a
while ago?
-Daniel

> 
> Christian.
> 
> > -Daniel
> > 
> > > Thanks,
> > > Christian.
> > > 
> > > Am 18.08.21 um 12:54 schrieb Christian König:
> > > > Only the DRM GPU scheduler, radeon and amdgpu where using them and they 
> > > > depend
> > > > on a non existing config option to actually emit some code.
> > > > 
> > > > v2: keep the signal path as is for now
> > > > 
> > > > Signed-off-by: Christian König 
> > > > ---
> > > >drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 10 +-
> > > >drivers/gpu/drm/radeon/radeon_fence.c | 24 
> > > > ---
> > > >drivers/gpu/drm/scheduler/sched_fence.c   | 18 ++---
> > > >include/linux/dma-fence.h | 22 -
> > > >4 files changed, 7 insertions(+), 67 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
> > > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > > > index 0b1c48590c43..c65994e382bd 100644
> > > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > > > @@ -246,7 +246,6 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
> > > > struct amdgpu_fence_driver *drv = >fence_drv;
> > > > struct amdgpu_device *adev = ring->adev;
> > > > uint32_t seq, last_seq;
> > > > -   int r;
> > > > do {
> > > > last_seq = atomic_read(>fence_drv.last_seq);
> > > > @@ -278,12 +277,7 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
> > > > if (!fence)
> > > > continue;
> > > > -   r = dma_fence_signal(fence);
> > > > -   if (!r)
> > > > -   DMA_FENCE_TRACE(fence, "signaled from irq 
> > > > context\n");
> > > > -   else
> > > > -   BUG();
> > > > -
> > > > +   dma_fence_signal(fence);
> > > > dma_fence_put(fence);
> > > > pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
> > > > pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
> > > > @@ -639,8 +633,6 @@ static bool amdgpu_fence_enable_signaling(struct 
> > > > dma_fence *f)
> > > > if (!timer_pending(>fence_drv.fallback_timer))
> > > > amdgpu_fence_schedule_fallback(ring);
> > > > -   DMA_FENCE_TRACE(>base, "armed on ring %i!\n", ring->idx);
> > > > -
> > > > return true;
> > > >}
> > > > diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
> > > > b/drivers/gpu/drm/radeon/radeon_fence.c
> > > > index 18f2c2e0dfb3..3f351d222cbb 100644
> > > > --- a/drivers/gpu/drm/radeon/radeon_fence.c
> > > > +++ b/drivers/gpu/drm/radeon/radeon_fence.c
> > > > @@ -176,18 +176,11 @@ static int 
> > > > radeon_fence_check_signaled(wait_queue_entry_t *wait, unsigned mode,
> > > >  */
> > > > seq = 
> > > > atomic64_read(>rdev->fence_drv[fence->ring].last_seq);
> > > > if (seq >= fence->seq) {
> > > > -   int ret = dma_fence_signal_locked(>base);
> > > > -
> > > > -   if (!ret)
> > > > -   DMA_FENCE_TRACE(>base, "signaled from 
> > > > irq context\n");
> > > > -   else
> > > > -   DMA_FENCE_TRACE(>base, "was already 
> > > > signaled\n");
> > > > -
> > > > +   dma_fence_signal_locked(>base);
> > > > radeon_irq_kms_sw_irq_put(fence->rdev, fence->ring);
> > > > __remove_wait_queue(>rdev->fence_queue, 
> > > > >fence_wake);
> > > > dma_fence_put(>base);
> 

Re: [RFC PATCH 0/4] Allow to use DRM fbdev emulation layer with CONFIG_FB disabled

2021-08-27 Thread Daniel Vetter
On Fri, Aug 27, 2021 at 07:50:23PM +0200, Thomas Zimmermann wrote:
> Hi
> 
> Am 27.08.21 um 12:00 schrieb Javier Martinez Canillas:
> > This patch series splits the fbdev core support in two different Kconfig
> > symbols: FB and FB_CORE. The motivation for this is to allow CONFIG_FB to
> > be disabled, while still using fbcon with the DRM fbdev emulation layer.
> 
> I'm skeptical. DRM's fbdev emulation is not just the console emulation, it's
> a full fbdev device. You can see the related device file as /dev/fb*.
> Providing the file while having CONFIG_FB disabled doesn't make much sense
> to me. I know it's not pretty, but it's consistent at least.
> 
> If you want to remove fbdev, you could try to untangle fbdev and the console
> emulation such that DRM can set up a console by itself. Old fbdev drives
> would also set up the console individually.

Yeah given the horrendous security track record of all that code, and the
maze of handover we have (stuff like flicker free boot and all that) I'm
wondering whether typing a new drmcon wouldn't be faster and a lot more
maintainable.

With drm_client this shouldn't be too much work at least for the drm code.

> Another low-hangling fruit is a config option to enable/disable the fbdev
> userspace interface (i.e., dev/fb*). Disabling the interface would remove
> the rsp mmap of the fbdev graphics buffer. We sometimes have to use an extra
> shadow buffer because mmap requires non-moving buffers. Without mmap we
> might be able to avoid some of the costly internal memcpys for some of our
> drivers.

And yeah stuff like that wouldn't be needed for drmcon either.
-Daniel

> 
> Best regards
> Thomas
> 
> > 
> > The reason for doing this is that now with simpledrm we could just boot
> > with simpledrm -> real DRM driver, without needing any legacy fbdev driver
> > (e.g: efifb or simplefb) even for the early console.
> > 
> > We want to do that in the Fedora kernel, but currently need to keep option
> > CONFIG_FB enabled and all fbdev drivers explicitly disabled, which makes
> > the configuration harder to maintain.
> > 
> > It is a RFC because I'm not that familiar with the fbdev core, but I have
> > tested and works with CONFIG_DRM_FBDEV_EMULATION=y and CONFIG_FB disabled.
> > This config automatically disables all the fbdev drivers that is our goal.
> > 
> > Patch 1/4 is just a clean up, patch 2/4 moves a couple of functions out of
> > fbsysfs.o, that are not related to sysfs attributes creation and finally
> > patch 3/4 makes the fbdev split that is mentioned above.
> > 
> > Patch 4/4 makes the DRM fbdev emulation depend on the new FB_CORE symbol
> > instead of FB. This could be done as a follow-up but for completeness is
> > also included in this series.
> > 
> > Best regards,
> > Javier
> > 
> > 
> > Javier Martinez Canillas (4):
> >fbdev: Rename fb_*_device() functions names to match what they do
> >fbdev: Move framebuffer_{alloc,release}() functions to fbmem.c
> >fbdev: Split frame buffer support in FB and FB_CORE symbols
> >drm: Make fbdev emulation depend on FB_CORE instead of FB
> > 
> >   arch/x86/Makefile  |  2 +-
> >   arch/x86/video/Makefile|  2 +-
> >   drivers/gpu/drm/Kconfig|  2 +-
> >   drivers/video/console/Kconfig  |  2 +-
> >   drivers/video/fbdev/Kconfig| 57 +-
> >   drivers/video/fbdev/core/Makefile  | 13 +++--
> >   drivers/video/fbdev/core/fbmem.c   | 73 ++--
> >   drivers/video/fbdev/core/fbsysfs.c | 77 +-
> >   include/linux/fb.h | 18 ++-
> >   9 files changed, 134 insertions(+), 112 deletions(-)
> > 
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
> 




-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[pull] amdgpu, amdkfd drm-next-5.15

2021-08-27 Thread Alex Deucher
Hi Dave, Daniel,

Fixes for 5.15.

The following changes since commit 90a9266269eb9f71af1f323c33e1dca53527bd22:

  drm/amdgpu: Cancel delayed work when GFXOFF is disabled (2021-08-20 12:09:44 
-0400)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-next-5.15-2021-08-27

for you to fetch changes up to 61d861cf478576d85d6032f864360a34b26084b1:

  drm/amd/display: Move AllowDRAMSelfRefreshOrDRAMClockChangeInVblank to 
bounding box (2021-08-26 13:57:33 -0400)


amd-drm-next-5.15-2021-08-27:

amdgpu:
- PLL fix for SI
- Misc code cleanups
- RAS fixes
- PSP cleanups
- Polaris UVD/VCE suspend fixes
- aldebaran fixes
- DCN3.x mclk fixes

amdkfd:
- CWSR fixes for arcturus and aldebaran
- SVM fixes


Aurabindo Pillai (2):
  drm/amd/display: Update number of DCN3 clock states
  drm/amd/display: Remove duplicate dml init

Borislav Petkov (1):
  drm/amdgpu: Fix build with missing pm_suspend_target_state module export

Candice Li (2):
  drm/amd/amdgpu: add name field back to ras_common_if
  drm/amd/amdgpu: consolidate PSP TA init shared buf functions

Christophe JAILLET (2):
  drm/amdgpu: switch from 'pci_' to 'dma_' API
  drm/radeon: switch from 'pci_' to 'dma_' API

Eric Yang (1):
  drm/amd/display: refactor riommu invalidation wa

Evan Quan (3):
  drm/amdgpu: add missing cleanups for Polaris12 UVD/VCE on suspend
  drm/amdgpu: add missing cleanups for more ASICs on UVD/VCE suspend
  drm/amdgpu: drop redundant cancel_delayed_work_sync call

Hawking Zhang (1):
  drm/amdgpu: disable GFX CGCG in aldebaran

Jerry (Fangzhi) Zuo (1):
  drm/amd/display: Update bounding box states (v2)

John Clements (4):
  drm/amdgpu: Add driver infrastructure for MCA RAS
  drm/amdgpu: Update RAS XGMI Error Query
  drm/amdgpu: Add support for RAS XGMI err query
  drm/amdgpu: Clear RAS interrupt status on aldebaran

Mukul Joshi (1):
  drm/amdkfd: CWSR with sw scheduler on Aldebaran and Arcturus

Nicholas Kazlauskas (1):
  drm/amd/display: Move AllowDRAMSelfRefreshOrDRAMClockChangeInVblank to 
bounding box

Philip Yang (2):
  drm/amdkfd: check access permisson to restore retry fault
  drm/amdkfd: map SVM range with correct access permission

Praful Swarnakar (1):
  drm/amd/display: Add Logging for HDMI color depth information

Sean Keely (1):
  drm/amdkfd: Account for SH/SE count when setting up cu masks.

Shashank Sharma (1):
  drm/amdgpu/OLAND: clip the ref divider max value

Yifan Zhang (1):
  drm/amdgpu: rename amdgpu_bo_get_preferred_pin_domain

 drivers/gpu/drm/amd/amdgpu/Makefile|   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu.h|   4 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c   |   2 +-
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c   |   1 +
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c|   3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c  |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h  |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c   |   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c|   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c|  21 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c   |   2 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c| 117 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h|  72 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |   8 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_pll.c|  20 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_pll.h|   3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c| 142 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h|   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c|   1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c|   1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c|   2 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c |   7 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c   |  69 -
 drivers/gpu/drm/amd/amdgpu/atombios_crtc.c |   2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c |   3 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c  |  19 ++-
 drivers/gpu/drm/amd/amdgpu/mca_v3_0.c  | 125 
 drivers/gpu/drm/amd/amdgpu/mca_v3_0.h  |  26 
 drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c |  34 -
 drivers/gpu/drm/amd/amdgpu/soc15.c |   2 -
 drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c  |  24 +++
 drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c  |  24 +++
 drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c  |  25 +++-
 drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c  |  24 +++
 

Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

2021-08-27 Thread Christian König
Yeah, that's what I meant with that the start of processing a job is a 
bit swampy defined.


Jobs overload, but we simply don't have another good indicator that a 
job started except that the previous one completed.


It's still better than starting the timer when pushing the job to the 
ring buffer, because that is completely off.


Christian.

Am 27.08.21 um 20:22 schrieb Andrey Grodzovsky:
As I mentioned to Monk before - what about cases such as in this test 
- 
https://gitlab.freedesktop.org/mesa/drm/-/commit/bc21168fa924d3fc4a000492e861f50a1a135b25 

Here you don't have serialized sequence where when jobs finishes 
processing and second starts, they execute together  concurrently - 
for those cases seems
to me restarting the timer for the second job from scratch will let it 
hang much longer then allowed by TO value.


Andrey

On 2021-08-27 10:29 a.m., Christian König wrote:

I don't think that makes sense.

See we don't want to start the time when the job is inserted into the 
ring buffer, but rather when it starts processing.


Starting processing is a bit swampy defined, but just starting the 
timer when the previous job completes should be fine enough.


Christian.

Am 27.08.21 um 15:57 schrieb Andrey Grodzovsky:
The TS represents the point in time when the job was inserted into 
the pending list.
I don't think it matters when it actually starts to be processed, 
what matters is when this job was inserted into pending list because 
right at that point you arm the TO timer (when no other is running 
already)
and so when the previous job completes and you cancel and rearm 
again you can use that TS from the next job in pending list to 
calculate how much time has actually left for it to run before TDR 
must be initiated
and not just give it again full TO value to run even if it has 
already been running for a while.


Also, i am not sure also about the assumption that what we measure 
is processing by HW, what we measure is from the moment it was 
scheduled to ring to the moment the job completed (EOP event). At 
least that what our TDR timer measures and so it makes sense to set 
the TS at this point.


Andrey

On 2021-08-27 3:20 a.m., Liu, Monk wrote:

[AMD Official Use Only]

what is that 'ts' representing for ? it looks to me the jiffies 
that it get scheduled to the ring,  but a job scheduled to the ring 
doesn't represent it's being processed by hw.


Thanks

--
Monk Liu | Cloud-GPU Core team
--

-Original Message-
From: Grodzovsky, Andrey 
Sent: Friday, August 27, 2021 4:14 AM
To: Liu, Monk ; amd-...@lists.freedesktop.org; 
Koenig, Christian 

Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/sched: fix the bug of time out 
calculation(v3)


Attached quick patch for per job TTL calculation to make more 
precises next timer expiration. It's on top of the patch in this 
thread. Let me know if this makes sense.


Andrey

On 2021-08-26 10:03 a.m., Andrey Grodzovsky wrote:

On 2021-08-26 12:55 a.m., Monk Liu wrote:

issue:
in cleanup_job the cancle_delayed_work will cancel a TO timer even
the its corresponding job is still running.

fix:
do not cancel the timer in cleanup_job, instead do the cancelling
only when the heading job is signaled, and if there is a "next" job
we start_timeout again.

v2:
further cleanup the logic, and do the TDR timer cancelling if the
signaled job is the last one in its scheduler.

v3:
change the issue description
remove the cancel_delayed_work in the begining of the cleanup_job
recover the implement of drm_sched_job_begin.

TODO:
1)introduce pause/resume scheduler in job_timeout to serial the
handling of scheduler and job_timeout.
2)drop the bad job's del and insert in scheduler due to above
serialization (no race issue anymore with the serialization)

Signed-off-by: Monk Liu 
---
   drivers/gpu/drm/scheduler/sched_main.c | 25
++---
   1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c
b/drivers/gpu/drm/scheduler/sched_main.c
index a2a9536..ecf8140 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -676,13 +676,7 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   {
   struct drm_sched_job *job, *next;
   -    /*
- * Don't destroy jobs while the timeout worker is running OR
thread
- * is being parked and hence assumed to not touch pending_list
- */
-    if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
-    !cancel_delayed_work(>work_tdr)) ||
-    kthread_should_park())
+    if (kthread_should_park())
   return NULL;


I actually don't see why we need to keep the above, on the other side
(in drm_sched_stop) we won't touch the pending list anyway until 
sched

thread came to full stop (kthread_park). If you do see a reason why
this needed then a comment should be here i think.

Andrey




[PATCH] drm/amdgpu/swsmu: fix spelling mistake "minimun" -> "minimum"

2021-08-27 Thread Colin King
From: Colin Ian King 

There are three identical spelling mistakes in dev_err messages.
Fix these.

Signed-off-by: Colin Ian King 
---
 drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 2 +-
 drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c  | 2 +-
 drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
index ad52f7ecfb87..629bb8e926fb 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
@@ -1869,7 +1869,7 @@ static int vangogh_od_edit_dpm_table(struct smu_context 
*smu, enum PP_OD_DPM_TAB
} else {
if (smu->gfx_actual_hard_min_freq > 
smu->gfx_actual_soft_max_freq) {
dev_err(smu->adev->dev,
-   "The setting minimun sclk (%d) MHz is 
greater than the setting maximum sclk (%d) MHz\n",
+   "The setting minimum sclk (%d) MHz is 
greater than the setting maximum sclk (%d) MHz\n",
smu->gfx_actual_hard_min_freq,
smu->gfx_actual_soft_max_freq);
return -EINVAL;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
index b39138041141..5aa175e12a78 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
@@ -426,7 +426,7 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu,
} else {
if (smu->gfx_actual_hard_min_freq > 
smu->gfx_actual_soft_max_freq) {
dev_err(smu->adev->dev,
-   "The setting minimun sclk (%d) MHz is 
greater than the setting maximum sclk (%d) MHz\n",
+   "The setting minimum sclk (%d) MHz is 
greater than the setting maximum sclk (%d) MHz\n",
smu->gfx_actual_hard_min_freq,
smu->gfx_actual_soft_max_freq);
return -EINVAL;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c
index 0f17c2522c85..627ba2eec7fd 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c
@@ -731,7 +731,7 @@ static int yellow_carp_od_edit_dpm_table(struct smu_context 
*smu, enum PP_OD_DPM
} else {
if (smu->gfx_actual_hard_min_freq > 
smu->gfx_actual_soft_max_freq) {
dev_err(smu->adev->dev,
-   "The setting minimun sclk (%d) MHz is 
greater than the setting maximum sclk (%d) MHz\n",
+   "The setting minimum sclk (%d) MHz is 
greater than the setting maximum sclk (%d) MHz\n",
smu->gfx_actual_hard_min_freq,
smu->gfx_actual_soft_max_freq);
return -EINVAL;
-- 
2.32.0



[PATCH] drm: i810: Fix spelling mistake "constext" -> "context"

2021-08-27 Thread Colin King
From: Colin Ian King 

There is a spelling mistake in a printk message. Fix it.

Signed-off-by: Colin Ian King 
---
 drivers/gpu/drm/i810/i810_dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index 9fb4dd63342f..ef141d217a72 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -479,7 +479,7 @@ static void i810EmitContextVerified(struct drm_device *dev,
OUT_RING(tmp);
j++;
} else
-   printk("constext state dropped!!!\n");
+   printk("context state dropped!!!\n");
}
 
if (j & 1)
-- 
2.32.0



Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

2021-08-27 Thread Andrey Grodzovsky

Sure then.

Andrey

On 2021-08-27 2:30 p.m., Christian König wrote:
Yeah, that's what I meant with that the start of processing a job is a 
bit swampy defined.


Jobs overload, but we simply don't have another good indicator that a 
job started except that the previous one completed.


It's still better than starting the timer when pushing the job to the 
ring buffer, because that is completely off.


Christian.

Am 27.08.21 um 20:22 schrieb Andrey Grodzovsky:
As I mentioned to Monk before - what about cases such as in this test 
- 
https://gitlab.freedesktop.org/mesa/drm/-/commit/bc21168fa924d3fc4a000492e861f50a1a135b25 

Here you don't have serialized sequence where when jobs finishes 
processing and second starts, they execute together concurrently - 
for those cases seems
to me restarting the timer for the second job from scratch will let 
it hang much longer then allowed by TO value.


Andrey

On 2021-08-27 10:29 a.m., Christian König wrote:

I don't think that makes sense.

See we don't want to start the time when the job is inserted into 
the ring buffer, but rather when it starts processing.


Starting processing is a bit swampy defined, but just starting the 
timer when the previous job completes should be fine enough.


Christian.

Am 27.08.21 um 15:57 schrieb Andrey Grodzovsky:
The TS represents the point in time when the job was inserted into 
the pending list.
I don't think it matters when it actually starts to be processed, 
what matters is when this job was inserted into pending list 
because right at that point you arm the TO timer (when no other is 
running already)
and so when the previous job completes and you cancel and rearm 
again you can use that TS from the next job in pending list to 
calculate how much time has actually left for it to run before TDR 
must be initiated
and not just give it again full TO value to run even if it has 
already been running for a while.


Also, i am not sure also about the assumption that what we measure 
is processing by HW, what we measure is from the moment it was 
scheduled to ring to the moment the job completed (EOP event). At 
least that what our TDR timer measures and so it makes sense to set 
the TS at this point.


Andrey

On 2021-08-27 3:20 a.m., Liu, Monk wrote:

[AMD Official Use Only]

what is that 'ts' representing for ? it looks to me the jiffies 
that it get scheduled to the ring,  but a job scheduled to the 
ring doesn't represent it's being processed by hw.


Thanks

--
Monk Liu | Cloud-GPU Core team
--

-Original Message-
From: Grodzovsky, Andrey 
Sent: Friday, August 27, 2021 4:14 AM
To: Liu, Monk ; amd-...@lists.freedesktop.org; 
Koenig, Christian 

Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/sched: fix the bug of time out 
calculation(v3)


Attached quick patch for per job TTL calculation to make more 
precises next timer expiration. It's on top of the patch in this 
thread. Let me know if this makes sense.


Andrey

On 2021-08-26 10:03 a.m., Andrey Grodzovsky wrote:

On 2021-08-26 12:55 a.m., Monk Liu wrote:

issue:
in cleanup_job the cancle_delayed_work will cancel a TO timer even
the its corresponding job is still running.

fix:
do not cancel the timer in cleanup_job, instead do the cancelling
only when the heading job is signaled, and if there is a "next" job
we start_timeout again.

v2:
further cleanup the logic, and do the TDR timer cancelling if the
signaled job is the last one in its scheduler.

v3:
change the issue description
remove the cancel_delayed_work in the begining of the cleanup_job
recover the implement of drm_sched_job_begin.

TODO:
1)introduce pause/resume scheduler in job_timeout to serial the
handling of scheduler and job_timeout.
2)drop the bad job's del and insert in scheduler due to above
serialization (no race issue anymore with the serialization)

Signed-off-by: Monk Liu 
---
   drivers/gpu/drm/scheduler/sched_main.c | 25
++---
   1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c
b/drivers/gpu/drm/scheduler/sched_main.c
index a2a9536..ecf8140 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -676,13 +676,7 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   {
   struct drm_sched_job *job, *next;
   -    /*
- * Don't destroy jobs while the timeout worker is running OR
thread
- * is being parked and hence assumed to not touch pending_list
- */
-    if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
- !cancel_delayed_work(>work_tdr)) ||
-    kthread_should_park())
+    if (kthread_should_park())
   return NULL;


I actually don't see why we need to keep the above, on the other 
side
(in drm_sched_stop) we won't touch the pending list anyway until 
sched

thread came to full stop (kthread_park). If you do see a reason why
this needed then a 

[Bug 211425] [drm:atom_op_jump] *ERROR* atombios stuck in loop for more than 20secs aborting

2021-08-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=211425

Andreas (icedragon...@web.de) changed:

   What|Removed |Added

 Kernel Version|5.13.11 |5.13.13

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

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

Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

2021-08-27 Thread Andrey Grodzovsky
As I mentioned to Monk before - what about cases such as in this test - 
https://gitlab.freedesktop.org/mesa/drm/-/commit/bc21168fa924d3fc4a000492e861f50a1a135b25
Here you don't have serialized sequence where when jobs finishes 
processing and second starts, they execute together  concurrently - for 
those cases seems
to me restarting the timer for the second job from scratch will let it 
hang much longer then allowed by TO value.


Andrey

On 2021-08-27 10:29 a.m., Christian König wrote:

I don't think that makes sense.

See we don't want to start the time when the job is inserted into the 
ring buffer, but rather when it starts processing.


Starting processing is a bit swampy defined, but just starting the 
timer when the previous job completes should be fine enough.


Christian.

Am 27.08.21 um 15:57 schrieb Andrey Grodzovsky:
The TS represents the point in time when the job was inserted into 
the pending list.
I don't think it matters when it actually starts to be processed, 
what matters is when this job was inserted into pending list because 
right at that point you arm the TO timer (when no other is running 
already)
and so when the previous job completes and you cancel and rearm again 
you can use that TS from the next job in pending list to calculate 
how much time has actually left for it to run before TDR must be 
initiated
and not just give it again full TO value to run even if it has 
already been running for a while.


Also, i am not sure also about the assumption that what we measure is 
processing by HW, what we measure is from the moment it was scheduled 
to ring to the moment the job completed (EOP event). At least that 
what our TDR timer measures and so it makes sense to set the TS at 
this point.


Andrey

On 2021-08-27 3:20 a.m., Liu, Monk wrote:

[AMD Official Use Only]

what is that 'ts' representing for ? it looks to me the jiffies that 
it get scheduled to the ring,  but a job scheduled to the ring 
doesn't represent it's being processed by hw.


Thanks

--
Monk Liu | Cloud-GPU Core team
--

-Original Message-
From: Grodzovsky, Andrey 
Sent: Friday, August 27, 2021 4:14 AM
To: Liu, Monk ; amd-...@lists.freedesktop.org; 
Koenig, Christian 

Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

Attached quick patch for per job TTL calculation to make more 
precises next timer expiration. It's on top of the patch in this 
thread. Let me know if this makes sense.


Andrey

On 2021-08-26 10:03 a.m., Andrey Grodzovsky wrote:

On 2021-08-26 12:55 a.m., Monk Liu wrote:

issue:
in cleanup_job the cancle_delayed_work will cancel a TO timer even
the its corresponding job is still running.

fix:
do not cancel the timer in cleanup_job, instead do the cancelling
only when the heading job is signaled, and if there is a "next" job
we start_timeout again.

v2:
further cleanup the logic, and do the TDR timer cancelling if the
signaled job is the last one in its scheduler.

v3:
change the issue description
remove the cancel_delayed_work in the begining of the cleanup_job
recover the implement of drm_sched_job_begin.

TODO:
1)introduce pause/resume scheduler in job_timeout to serial the
handling of scheduler and job_timeout.
2)drop the bad job's del and insert in scheduler due to above
serialization (no race issue anymore with the serialization)

Signed-off-by: Monk Liu 
---
   drivers/gpu/drm/scheduler/sched_main.c | 25
++---
   1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c
b/drivers/gpu/drm/scheduler/sched_main.c
index a2a9536..ecf8140 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -676,13 +676,7 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   {
   struct drm_sched_job *job, *next;
   -    /*
- * Don't destroy jobs while the timeout worker is running OR
thread
- * is being parked and hence assumed to not touch pending_list
- */
-    if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
-    !cancel_delayed_work(>work_tdr)) ||
-    kthread_should_park())
+    if (kthread_should_park())
   return NULL;


I actually don't see why we need to keep the above, on the other side
(in drm_sched_stop) we won't touch the pending list anyway until sched
thread came to full stop (kthread_park). If you do see a reason why
this needed then a comment should be here i think.

Andrey



spin_lock(>job_list_lock);
@@ -693,17 +687,21 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   if (job && dma_fence_is_signaled(>s_fence->finished)) {
   /* remove job from pending_list */
   list_del_init(>list);
+
+    /* cancel this job's TO timer */
+    cancel_delayed_work(>work_tdr);
   /* make the scheduled timestamp more accurate */
   next = 

Re: [PATCH v3] drm/amd/pm: And destination bounds checking to struct copy

2021-08-27 Thread Alex Deucher
Applied.  Thanks!

Alex

On Thu, Aug 26, 2021 at 11:16 PM Kees Cook  wrote:
>
> In preparation for FORTIFY_SOURCE performing compile-time and run-time
> field bounds checking for memcpy(), memmove(), and memset(), avoid
> intentionally writing across neighboring fields.
>
> The "Board Parameters" members of the structs:
> struct atom_smc_dpm_info_v4_5
> struct atom_smc_dpm_info_v4_6
> struct atom_smc_dpm_info_v4_7
> struct atom_smc_dpm_info_v4_10
> are written to the corresponding members of the corresponding PPTable_t
> variables, but they lack destination size bounds checking, which means
> the compiler cannot verify at compile time that this is an intended and
> safe memcpy().
>
> Since the header files are effectively immutable[1] and a struct_group()
> cannot be used, nor a common struct referenced by both sides of the
> memcpy() arguments, add a new helper, amdgpu_memcpy_trailing(), to
> perform the bounds checking at compile time. Replace the open-coded
> memcpy()s with amdgpu_memcpy_trailing() which includes enough context
> for the bounds checking.
>
> "objdump -d" shows no object code changes.
>
> [1] https://lore.kernel.org/lkml/e56aad3c-a06f-da07-f491-a894a570d...@amd.com
>
> Cc: "Christian König" 
> Cc: "Pan, Xinhui" 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Cc: Hawking Zhang 
> Cc: Feifei Xu 
> Cc: Likun Gao 
> Cc: Jiawei Gu 
> Cc: Evan Quan 
> Cc: amd-...@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org
> Reviewed-by: Lijo Lazar 
> Acked-by: Alex Deucher 
> Signed-off-by: Kees Cook 
> ---
> v3: rename amdgpu_memcpy_trailing() to smu_memcpy_trailing()
> v2: 
> https://lore.kernel.org/lkml/20210825161957.3904130-1-keesc...@chromium.org
> v1: 
> https://lore.kernel.org/lkml/20210819201441.3545027-1-keesc...@chromium.org
> ---
>  drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h   | 24 +++
>  .../gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c |  6 ++---
>  .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c   |  8 +++
>  .../drm/amd/pm/swsmu/smu13/aldebaran_ppt.c|  5 ++--
>  4 files changed, 32 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h 
> b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
> index 715b4225f5ee..8156729c370b 100644
> --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
> +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
> @@ -1335,6 +1335,30 @@ enum smu_cmn2asic_mapping_type {
>  #define WORKLOAD_MAP(profile, workload) \
> [profile] = {1, (workload)}
>
> +/**
> + * smu_memcpy_trailing - Copy the end of one structure into the middle of 
> another
> + *
> + * @dst: Pointer to destination struct
> + * @first_dst_member: The member name in @dst where the overwrite begins
> + * @last_dst_member: The member name in @dst where the overwrite ends after
> + * @src: Pointer to the source struct
> + * @first_src_member: The member name in @src where the copy begins
> + *
> + */
> +#define smu_memcpy_trailing(dst, first_dst_member, last_dst_member,   \
> +   src, first_src_member) \
> +({\
> +   size_t __src_offset = offsetof(typeof(*(src)), first_src_member);  \
> +   size_t __src_size = sizeof(*(src)) - __src_offset; \
> +   size_t __dst_offset = offsetof(typeof(*(dst)), first_dst_member);  \
> +   size_t __dst_size = offsetofend(typeof(*(dst)), last_dst_member) - \
> +   __dst_offset;  \
> +   BUILD_BUG_ON(__src_size != __dst_size);\
> +   __builtin_memcpy((u8 *)(dst) + __dst_offset,   \
> +(u8 *)(src) + __src_offset,   \
> +__dst_size);  \
> +})
> +
>  #if !defined(SWSMU_CODE_LAYER_L2) && !defined(SWSMU_CODE_LAYER_L3) && 
> !defined(SWSMU_CODE_LAYER_L4)
>  int smu_get_power_limit(void *handle,
> uint32_t *limit,
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c 
> b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
> index 273df66cac14..e343cc218990 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
> @@ -483,10 +483,8 @@ static int arcturus_append_powerplay_table(struct 
> smu_context *smu)
>
> if ((smc_dpm_table->table_header.format_revision == 4) &&
> (smc_dpm_table->table_header.content_revision == 6))
> -   memcpy(_pptable->MaxVoltageStepGfx,
> -  _dpm_table->maxvoltagestepgfx,
> -  sizeof(*smc_dpm_table) - offsetof(struct 
> atom_smc_dpm_info_v4_6, maxvoltagestepgfx));
> -
> +   smu_memcpy_trailing(smc_pptable, MaxVoltageStepGfx, 
> BoardReserved,
> +   smc_dpm_table, maxvoltagestepgfx);
> return 0;
>  }

Re: [PATCH v2 0/4] Various fixes to pass libdrm hotunplug tests

2021-08-27 Thread Andrey Grodzovsky

Ping

Andrey

On 2021-08-26 1:27 p.m., Andrey Grodzovsky wrote:

Bunch of fixes to enable passing hotplug tests i previosly added
here[1] with latest code.
Once accepted I will enable the tests on libdrm side.

[1] - https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/172

v2:
Dropping VCE patch since relevant function already fixed in latest
code.
Moving IOMMU hnadling to TTM layer.

Andrey Grodzovsky (4):
   drm/ttm: Create pinned list
   drm/ttm: Clear all DMA mappings on demand
   drm/amdgpu: drm/amdgpu: Handle IOMMU enabled case
   drm/amdgpu: Add a UAPI flag for hot plug/unplug

  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  2 +
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c|  3 +-
  drivers/gpu/drm/ttm/ttm_bo.c   | 30 +--
  drivers/gpu/drm/ttm/ttm_device.c   | 45 ++
  drivers/gpu/drm/ttm/ttm_resource.c |  1 +
  include/drm/ttm/ttm_device.h   |  1 +
  include/drm/ttm/ttm_resource.h |  1 +
  7 files changed, 78 insertions(+), 5 deletions(-)



Re: [PATCH v6 01/11] moduleparam: add data member to struct kernel_param

2021-08-27 Thread jim . cromie
On Wed, Aug 25, 2021 at 11:13 AM Jason Baron  wrote:
>
>
>
> On 8/22/21 6:19 PM, Jim Cromie wrote:
> > Add a const void* data member to the struct, to allow attaching
> > private data that will be used soon by a setter method (via kp->data)
> > to perform more elaborate actions.
> >
> > To attach the data at compile time, add new macros:
> >

>
> I wonder if kp->arg can just be used for all this and avoid this patch 
> entirely?
>
> define something like:
>
> struct dd_bitmap_param {
> int bitmap;
> struct dyndbg_bitdesc *bitmap_arr;
> };
>
> and then just pass a pointer to it as 'arg' for module_param_cb? And then in
> the get/set callbacks you can use kp->bitmap and kp->bitmap_arr.
>

yes, thanks, this is working out nicely.
I think I was thrown off by the arg name,
if it had been called data, it would have slapped me

> Thanks,
>
> -Jason
>


Re: [RFC PATCH 0/4] Allow to use DRM fbdev emulation layer with CONFIG_FB disabled

2021-08-27 Thread Thomas Zimmermann

Hi

Am 27.08.21 um 12:00 schrieb Javier Martinez Canillas:

This patch series splits the fbdev core support in two different Kconfig
symbols: FB and FB_CORE. The motivation for this is to allow CONFIG_FB to
be disabled, while still using fbcon with the DRM fbdev emulation layer.


I'm skeptical. DRM's fbdev emulation is not just the console emulation, 
it's a full fbdev device. You can see the related device file as 
/dev/fb*. Providing the file while having CONFIG_FB disabled doesn't 
make much sense to me. I know it's not pretty, but it's consistent at least.


If you want to remove fbdev, you could try to untangle fbdev and the 
console emulation such that DRM can set up a console by itself. Old 
fbdev drives would also set up the console individually.


Another low-hangling fruit is a config option to enable/disable the 
fbdev userspace interface (i.e., dev/fb*). Disabling the interface would 
remove the rsp mmap of the fbdev graphics buffer. We sometimes have to 
use an extra shadow buffer because mmap requires non-moving buffers. 
Without mmap we might be able to avoid some of the costly internal 
memcpys for some of our drivers.


Best regards
Thomas



The reason for doing this is that now with simpledrm we could just boot
with simpledrm -> real DRM driver, without needing any legacy fbdev driver
(e.g: efifb or simplefb) even for the early console.

We want to do that in the Fedora kernel, but currently need to keep option
CONFIG_FB enabled and all fbdev drivers explicitly disabled, which makes
the configuration harder to maintain.

It is a RFC because I'm not that familiar with the fbdev core, but I have
tested and works with CONFIG_DRM_FBDEV_EMULATION=y and CONFIG_FB disabled.
This config automatically disables all the fbdev drivers that is our goal.

Patch 1/4 is just a clean up, patch 2/4 moves a couple of functions out of
fbsysfs.o, that are not related to sysfs attributes creation and finally
patch 3/4 makes the fbdev split that is mentioned above.

Patch 4/4 makes the DRM fbdev emulation depend on the new FB_CORE symbol
instead of FB. This could be done as a follow-up but for completeness is
also included in this series.

Best regards,
Javier


Javier Martinez Canillas (4):
   fbdev: Rename fb_*_device() functions names to match what they do
   fbdev: Move framebuffer_{alloc,release}() functions to fbmem.c
   fbdev: Split frame buffer support in FB and FB_CORE symbols
   drm: Make fbdev emulation depend on FB_CORE instead of FB

  arch/x86/Makefile  |  2 +-
  arch/x86/video/Makefile|  2 +-
  drivers/gpu/drm/Kconfig|  2 +-
  drivers/video/console/Kconfig  |  2 +-
  drivers/video/fbdev/Kconfig| 57 +-
  drivers/video/fbdev/core/Makefile  | 13 +++--
  drivers/video/fbdev/core/fbmem.c   | 73 ++--
  drivers/video/fbdev/core/fbsysfs.c | 77 +-
  include/linux/fb.h | 18 ++-
  9 files changed, 134 insertions(+), 112 deletions(-)



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



OpenPGP_signature
Description: OpenPGP digital signature


[Bug 214197] [Asus G713QY] RX6800M not usable after exiting Vulkan application

2021-08-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=214197

--- Comment #2 from Alex Deucher (alexdeuc...@gmail.com) ---
Does this patch fix the issue?
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=202ead5a3c589b0594a75cb99f080174f6851fed

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

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

Re: [PATCH v2 3/5] drm/msm/dp: Support up to 3 DP controllers

2021-08-27 Thread Bjorn Andersson
On Fri 27 Aug 00:20 CDT 2021, Stephen Boyd wrote:

> Quoting Bjorn Andersson (2021-08-25 16:42:31)
> > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > b/drivers/gpu/drm/msm/dp/dp_display.c
> > index 2c7de43f655a..4a6132c18e57 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > @@ -78,6 +78,8 @@ struct dp_display_private {
> > char *name;
> > int irq;
> >
> > +   int id;
> > +
> > /* state variables */
> > bool core_initialized;
> > bool hpd_irq_on;
> > @@ -115,8 +117,19 @@ struct dp_display_private {
> > struct dp_audio *audio;
> >  };
> >
> > +
> > +struct msm_dp_config {
> > +   phys_addr_t io_start[3];
> 
> Can this be made into another struct, like msm_dp_desc, that also
> indicates what type of DP connector it is, i.e. eDP vs DP? That would
> help me understand in modetest and /sys/class/drm what sort of connector
> is probing. dp_drm_connector_init() would need to pass the type of
> connector appropriately. Right now, eDP connectors still show up as DP
> instead of eDP in sysfs.
> 

I like it, will spin a v3 with this.

Regards,
Bjorn

> > +   size_t num_dp;
> > +};
> > +
> > +static const struct msm_dp_config sc7180_dp_cfg = {
> > +   .io_start = { 0x0ae9 },
> > +   .num_dp = 1,
> > +};
> > +
> >  static const struct of_device_id dp_dt_match[] = {
> > -   {.compatible = "qcom,sc7180-dp"},
> > +   { .compatible = "qcom,sc7180-dp", .data = _dp_cfg },
> > {}
> >  };
> >


[PATCH 2/2] drm/bridge: it66121: Wait for next bridge to be probed

2021-08-27 Thread Paul Cercueil
If run before the next bridge is initialized, of_drm_find_bridge() will
give us a NULL pointer.

If that's the case, return -EPROBE_DEFER; we may have more luck next
time.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/bridge/ite-it66121.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
b/drivers/gpu/drm/bridge/ite-it66121.c
index b130d01147c6..9dc41a7b9136 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -924,6 +924,9 @@ static int it66121_probe(struct i2c_client *client,
ctx->next_bridge = of_drm_find_bridge(ep);
of_node_put(ep);
 
+   if (!ctx->next_bridge)
+   return -EPROBE_DEFER;
+
i2c_set_clientdata(client, ctx);
mutex_init(>lock);
 
-- 
2.33.0



[PATCH 1/2] drm/bridge: it66121: Initialize {device,vendor}_ids

2021-08-27 Thread Paul Cercueil
These two arrays are populated with data read from the I2C device
through regmap_read(), and the data is then compared with hardcoded
vendor/product ID values of supported chips.

However, the return value of regmap_read() was never checked. This is
fine, as long as the two arrays are zero-initialized, so that we don't
compare the vendor/product IDs against whatever garbage is left on the
stack.

Address this issue by zero-initializing these two arrays.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/bridge/ite-it66121.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
b/drivers/gpu/drm/bridge/ite-it66121.c
index 2f2a09adb4bc..b130d01147c6 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -889,7 +889,7 @@ static irqreturn_t it66121_irq_threaded_handler(int irq, 
void *dev_id)
 static int it66121_probe(struct i2c_client *client,
 const struct i2c_device_id *id)
 {
-   u32 vendor_ids[2], device_ids[2], revision_id;
+   u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 };
struct device_node *ep;
int ret;
struct it66121_ctx *ctx;
-- 
2.33.0



[Bug 214197] [Asus G713QY] RX6800M not usable after exiting Vulkan application

2021-08-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=214197

Alex Deucher (alexdeuc...@gmail.com) changed:

   What|Removed |Added

 CC||alexdeuc...@gmail.com

--- Comment #1 from Alex Deucher (alexdeuc...@gmail.com) ---
Please attach your full dmesg output from boot through the problematic case.

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

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

Re: [Intel-gfx] [PATCH v2] drm/i915: Handle Intel igfx + Intel dgfx hybrid graphics setup

2021-08-27 Thread Tvrtko Ursulin



On 27/08/2021 15:39, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

In short this makes i915 work for hybrid setups (DRI_PRIME=1 with Mesa)
when rendering is done on Intel dgfx and scanout/composition on Intel
igfx.

Before this patch the driver was not quite ready for that setup, mainly
because it was able to emit a semaphore wait between the two GPUs, which
results in deadlocks because semaphore target location in HWSP is neither
shared between the two, nor mapped in both GGTT spaces.

To fix it the patch adds an additional check to a couple of relevant code
paths in order to prevent using semaphores for inter-engine
synchronisation between different driver instances.

Patch also moves singly used i915_gem_object_last_write_engine to be
private in its only calling unit (debugfs), while modifying it to only
show activity belonging to the respective driver instance.

What remains in this problem space is the question of the GEM busy ioctl.
We have a somewhat ambigous comment there saying only status of native
fences will be reported, which could be interpreted as either i915, or
native to the drm fd. For now I have decided to leave that as is, meaning
any i915 instance activity continues to be reported.

v2:
  * Avoid adding rq->i915. (Chris)

Signed-off-by: Tvrtko Ursulin 
---
  drivers/gpu/drm/i915/gem/i915_gem_object.h | 17 --
  drivers/gpu/drm/i915/i915_debugfs.c| 39 --
  drivers/gpu/drm/i915/i915_request.c| 12 ++-
  3 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 48112b9d76df..3043fcbd31bd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -503,23 +503,6 @@ i915_gem_object_finish_access(struct drm_i915_gem_object 
*obj)
i915_gem_object_unpin_pages(obj);
  }
  
-static inline struct intel_engine_cs *

-i915_gem_object_last_write_engine(struct drm_i915_gem_object *obj)
-{
-   struct intel_engine_cs *engine = NULL;
-   struct dma_fence *fence;
-
-   rcu_read_lock();
-   fence = dma_resv_get_excl_unlocked(obj->base.resv);
-   rcu_read_unlock();
-
-   if (fence && dma_fence_is_i915(fence) && !dma_fence_is_signaled(fence))
-   engine = to_request(fence)->engine;
-   dma_fence_put(fence);
-
-   return engine;
-}
-
  void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
 unsigned int cache_level);
  void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 04351a851586..55fd6191eb32 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -135,13 +135,46 @@ static const char *stringify_vma_type(const struct 
i915_vma *vma)
return "ppgtt";
  }
  
+static char *

+last_write_engine(struct drm_i915_private *i915,
+ struct drm_i915_gem_object *obj)
+{
+   struct intel_engine_cs *engine;
+   struct dma_fence *fence;
+   char *res = NULL;
+
+   rcu_read_lock();
+   fence = dma_resv_get_excl_unlocked(obj->base.resv);
+   rcu_read_unlock();
+
+   if (!fence || dma_fence_is_signaled(fence))
+   goto out;
+
+   if (!dma_fence_is_i915(fence)) {
+   res = "";
+   goto out;
+   }
+
+   engine = to_request(fence)->engine;
+   if (engine->gt->i915 != i915) {
+   res = "";
+   goto out;
+   }
+
+   res = engine->name;
+
+out:
+   dma_fence_put(fence);
+   return res;
+}
+
  void
  i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
  {
struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
-   struct intel_engine_cs *engine;
struct i915_vma *vma;
int pin_count = 0;
+   char *engine;
  
  	seq_printf(m, "%pK: %c%c%c %8zdKiB %02x %02x %s%s%s",

   >base,
@@ -230,9 +263,9 @@ i915_debugfs_describe_obj(struct seq_file *m, struct 
drm_i915_gem_object *obj)
if (i915_gem_object_is_framebuffer(obj))
seq_printf(m, " (fb)");
  
-	engine = i915_gem_object_last_write_engine(obj);

+   engine = last_write_engine(dev_priv, obj);
if (engine)
-   seq_printf(m, " (%s)", engine->name);
+   seq_printf(m, " (%s)", engine);


Or I zap this from the code altogether. Not sure it is very useful since 
the only caller is i915_gem_framebuffer debugfs file and how much it can 
care about maybe hitting the timing window when exclusive fence will 
contain something.


Regards,

Tvrtko


  }
  
  static int i915_gem_object_info(struct seq_file *m, void *data)

diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index ce446716d092..64adf619fe82 100644
--- 

Re: [v3 3/4] drm/panel: support for BOE and INX video mode panel

2021-08-27 Thread Doug Anderson
Hi,

On Fri, Aug 27, 2021 at 1:24 AM yangcong
 wrote:
>
> Add driver for BOE tv110c9m-ll3 and Inx hj110iz-01a panel
> both of those are 10.95" 1200x2000 panel.

Your commit message would be a good place to note design choices you
made in your patch. Maybe you might say:

Support for these two panels fits in nicely with the existing
panel-boe-tv101wum-nl6 driver as suggested by Sam [1]. The main things
we needed to handle were:
a) These panels need slightly longer delays in two places. Since these
new delays aren't much longer, let's just unconditionally increase
them for the driver.
b) One of these two panels doesn't support DSI HS mode so this patch
adds a flag for a panel to disable that.

[1] https://lore.kernel.org/r/yspasee6wd8dd...@ravnborg.org/

If you send a new version, maybe you could include prose similar to that?

> +   _INIT_DCS_CMD(0x4D, 0x21),
> +   _INIT_DCS_CMD(0x4E, 0x43),
> +   _INIT_DCS_CMD(0x51, 0x12),
> +   _INIT_DCS_CMD(0x52, 0x34),
> +   _INIT_DCS_CMD(0x55, 0x82, 0x02),
> +   _INIT_DCS_CMD(0x56, 0x04),
> +   _INIT_DCS_CMD(0x58, 0x21),
> +   _INIT_DCS_CMD(0x59, 0x30),
> +   _INIT_DCS_CMD(0x5A, 0xBA),  //9A

nit: the "//9A" above seems like it's leftover from something. Remove?

> +   _INIT_DCS_CMD(0x1F, 0xBA),//9A
> +   _INIT_DCS_CMD(0x20, 0xA0),
> +
> +   _INIT_DCS_CMD(0x26, 0xBA),//9A
> +   _INIT_DCS_CMD(0x27, 0xA0),
> +
> +   _INIT_DCS_CMD(0x33, 0xBA),//9A
> +   _INIT_DCS_CMD(0x34, 0xA0),
> +
> +   _INIT_DCS_CMD(0x3F, 0xE0),
> +
> +   _INIT_DCS_CMD(0x40, 0x00),
> +
> +   _INIT_DCS_CMD(0x44, 0x00),
> +   _INIT_DCS_CMD(0x45, 0x40),
> +
> +   _INIT_DCS_CMD(0x48, 0xBA),//9A
> +   _INIT_DCS_CMD(0x49, 0xA0),
> +
> +   _INIT_DCS_CMD(0x5B, 0x00),
> +   _INIT_DCS_CMD(0x5C, 0x00),
> +   _INIT_DCS_CMD(0x5D, 0x00),
> +   _INIT_DCS_CMD(0x5E, 0xD0),
> +
> +   _INIT_DCS_CMD(0x61, 0xBA),//9A
> +   _INIT_DCS_CMD(0x62, 0xA0),

More random //9A to remove above?


> @@ -515,7 +1363,7 @@ static int boe_panel_unprepare(struct drm_panel *panel)
> regulator_disable(boe->pp3300);
> } else {
> gpiod_set_value(boe->enable_gpio, 0);
> -   usleep_range(500, 1000);
> +   usleep_range(1000, 2000);
> regulator_disable(boe->avee);
> regulator_disable(boe->avdd);
> usleep_range(5000, 7000);
> @@ -556,7 +1404,7 @@ static int boe_panel_prepare(struct drm_panel *panel)
> if (ret < 0)
> goto poweroffavdd;
>
> -   usleep_range(5000, 1);
> +   usleep_range(1, 15000);

nit: how about using the range 1, 11000? Last I looked at
usleep_range() it almost always ended up at the longer of the two
times, so that will shave 4 ms off and get us nearly to where we were
without your change. The whole point of the range is to make the
system more power efficient for frequent operations (wakeup
combining), but that really doesn't matter for something as infrequent
as turning on a LCD.

Other than nits this looks fine to me and I'd be happy to add my
Reviewed-by to a version with nits fixed. I'm not really an expert on
MIPI panels but the convention of a big stream of binary commands
seems to match what other panels in this driver do, even if their
table of binary data isn't quite as long as yours (are all of yours
actually needed?). I'm happy to land this in drm-misc-next with Sam or
Thierry's Ack, too.


-Doug


Re: TTM tt size larger than buffer object?

2021-08-27 Thread Christian König

Am 27.08.21 um 15:55 schrieb Thomas Hellström:

Hi, Christian.

We have a use-case with i915 where the data representation of a buffer 
object is larger in system memory than in LMEM/VRAM. Hence we'd like 
to create a ttm_tt that is larger than the buffer object itself. 
Quickly auditing the TTM code it looks like that should be pretty 
safe, as ttm->num_pages is not really much accessed outside the tt 
code and the pool code where we're doing the right thing.


The additional data will really only be accessed by the blitter so 
when cpu-mapping, mapping just the original buffer object size is 
correct. However with swapping the additional data needs to be swapped 
out and the code is doing that correctly as well.


Do you think this is an acceptable solution?


Yes, I think that should work. Just haven't tested it yet.

I've been working on getting the core TTM code to use byte or rather an 
arbitrary size while the tt code should use the num_pages from it's own 
object.


The background is that we have a very similar use case on amdgpu which 
we might need to support.


Christian.



/Thomas






[PATCH v2] drm/i915: Handle Intel igfx + Intel dgfx hybrid graphics setup

2021-08-27 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

In short this makes i915 work for hybrid setups (DRI_PRIME=1 with Mesa)
when rendering is done on Intel dgfx and scanout/composition on Intel
igfx.

Before this patch the driver was not quite ready for that setup, mainly
because it was able to emit a semaphore wait between the two GPUs, which
results in deadlocks because semaphore target location in HWSP is neither
shared between the two, nor mapped in both GGTT spaces.

To fix it the patch adds an additional check to a couple of relevant code
paths in order to prevent using semaphores for inter-engine
synchronisation between different driver instances.

Patch also moves singly used i915_gem_object_last_write_engine to be
private in its only calling unit (debugfs), while modifying it to only
show activity belonging to the respective driver instance.

What remains in this problem space is the question of the GEM busy ioctl.
We have a somewhat ambigous comment there saying only status of native
fences will be reported, which could be interpreted as either i915, or
native to the drm fd. For now I have decided to leave that as is, meaning
any i915 instance activity continues to be reported.

v2:
 * Avoid adding rq->i915. (Chris)

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.h | 17 --
 drivers/gpu/drm/i915/i915_debugfs.c| 39 --
 drivers/gpu/drm/i915/i915_request.c| 12 ++-
 3 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 48112b9d76df..3043fcbd31bd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -503,23 +503,6 @@ i915_gem_object_finish_access(struct drm_i915_gem_object 
*obj)
i915_gem_object_unpin_pages(obj);
 }
 
-static inline struct intel_engine_cs *
-i915_gem_object_last_write_engine(struct drm_i915_gem_object *obj)
-{
-   struct intel_engine_cs *engine = NULL;
-   struct dma_fence *fence;
-
-   rcu_read_lock();
-   fence = dma_resv_get_excl_unlocked(obj->base.resv);
-   rcu_read_unlock();
-
-   if (fence && dma_fence_is_i915(fence) && !dma_fence_is_signaled(fence))
-   engine = to_request(fence)->engine;
-   dma_fence_put(fence);
-
-   return engine;
-}
-
 void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
 unsigned int cache_level);
 void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 04351a851586..55fd6191eb32 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -135,13 +135,46 @@ static const char *stringify_vma_type(const struct 
i915_vma *vma)
return "ppgtt";
 }
 
+static char *
+last_write_engine(struct drm_i915_private *i915,
+ struct drm_i915_gem_object *obj)
+{
+   struct intel_engine_cs *engine;
+   struct dma_fence *fence;
+   char *res = NULL;
+
+   rcu_read_lock();
+   fence = dma_resv_get_excl_unlocked(obj->base.resv);
+   rcu_read_unlock();
+
+   if (!fence || dma_fence_is_signaled(fence))
+   goto out;
+
+   if (!dma_fence_is_i915(fence)) {
+   res = "";
+   goto out;
+   }
+
+   engine = to_request(fence)->engine;
+   if (engine->gt->i915 != i915) {
+   res = "";
+   goto out;
+   }
+
+   res = engine->name;
+
+out:
+   dma_fence_put(fence);
+   return res;
+}
+
 void
 i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 {
struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
-   struct intel_engine_cs *engine;
struct i915_vma *vma;
int pin_count = 0;
+   char *engine;
 
seq_printf(m, "%pK: %c%c%c %8zdKiB %02x %02x %s%s%s",
   >base,
@@ -230,9 +263,9 @@ i915_debugfs_describe_obj(struct seq_file *m, struct 
drm_i915_gem_object *obj)
if (i915_gem_object_is_framebuffer(obj))
seq_printf(m, " (fb)");
 
-   engine = i915_gem_object_last_write_engine(obj);
+   engine = last_write_engine(dev_priv, obj);
if (engine)
-   seq_printf(m, " (%s)", engine->name);
+   seq_printf(m, " (%s)", engine);
 }
 
 static int i915_gem_object_info(struct seq_file *m, void *data)
diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index ce446716d092..64adf619fe82 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -1152,6 +1152,12 @@ __emit_semaphore_wait(struct i915_request *to,
return 0;
 }
 
+static bool
+can_use_semaphore_wait(struct i915_request *to, struct i915_request *from)
+{
+   return to->engine->gt == from->engine->gt;
+}
+
 static int
 

Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

2021-08-27 Thread Christian König

I don't think that makes sense.

See we don't want to start the time when the job is inserted into the 
ring buffer, but rather when it starts processing.


Starting processing is a bit swampy defined, but just starting the timer 
when the previous job completes should be fine enough.


Christian.

Am 27.08.21 um 15:57 schrieb Andrey Grodzovsky:
The TS represents the point in time when the job was inserted into the 
pending list.
I don't think it matters when it actually starts to be processed, what 
matters is when this job was inserted into pending list because right 
at that point you arm the TO timer (when no other is running already)
and so when the previous job completes and you cancel and rearm again 
you can use that TS from the next job in pending list to calculate how 
much time has actually left for it to run before TDR must be initiated
and not just give it again full TO value to run even if it has already 
been running for a while.


Also, i am not sure also about the assumption that what we measure is 
processing by HW, what we measure is from the moment it was scheduled 
to ring to the moment the job completed (EOP event). At least that 
what our TDR timer measures and so it makes sense to set the TS at 
this point.


Andrey

On 2021-08-27 3:20 a.m., Liu, Monk wrote:

[AMD Official Use Only]

what is that 'ts' representing for ? it looks to me the jiffies that 
it get scheduled to the ring,  but a job scheduled to the ring 
doesn't represent it's being processed by hw.


Thanks

--
Monk Liu | Cloud-GPU Core team
--

-Original Message-
From: Grodzovsky, Andrey 
Sent: Friday, August 27, 2021 4:14 AM
To: Liu, Monk ; amd-...@lists.freedesktop.org; 
Koenig, Christian 

Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

Attached quick patch for per job TTL calculation to make more 
precises next timer expiration. It's on top of the patch in this 
thread. Let me know if this makes sense.


Andrey

On 2021-08-26 10:03 a.m., Andrey Grodzovsky wrote:

On 2021-08-26 12:55 a.m., Monk Liu wrote:

issue:
in cleanup_job the cancle_delayed_work will cancel a TO timer even
the its corresponding job is still running.

fix:
do not cancel the timer in cleanup_job, instead do the cancelling
only when the heading job is signaled, and if there is a "next" job
we start_timeout again.

v2:
further cleanup the logic, and do the TDR timer cancelling if the
signaled job is the last one in its scheduler.

v3:
change the issue description
remove the cancel_delayed_work in the begining of the cleanup_job
recover the implement of drm_sched_job_begin.

TODO:
1)introduce pause/resume scheduler in job_timeout to serial the
handling of scheduler and job_timeout.
2)drop the bad job's del and insert in scheduler due to above
serialization (no race issue anymore with the serialization)

Signed-off-by: Monk Liu 
---
   drivers/gpu/drm/scheduler/sched_main.c | 25
++---
   1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c
b/drivers/gpu/drm/scheduler/sched_main.c
index a2a9536..ecf8140 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -676,13 +676,7 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   {
   struct drm_sched_job *job, *next;
   -    /*
- * Don't destroy jobs while the timeout worker is running OR
thread
- * is being parked and hence assumed to not touch pending_list
- */
-    if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
-    !cancel_delayed_work(>work_tdr)) ||
-    kthread_should_park())
+    if (kthread_should_park())
   return NULL;


I actually don't see why we need to keep the above, on the other side
(in drm_sched_stop) we won't touch the pending list anyway until sched
thread came to full stop (kthread_park). If you do see a reason why
this needed then a comment should be here i think.

Andrey



spin_lock(>job_list_lock);
@@ -693,17 +687,21 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   if (job && dma_fence_is_signaled(>s_fence->finished)) {
   /* remove job from pending_list */
   list_del_init(>list);
+
+    /* cancel this job's TO timer */
+    cancel_delayed_work(>work_tdr);
   /* make the scheduled timestamp more accurate */
   next = list_first_entry_or_null(>pending_list,
   typeof(*next), list);
-    if (next)
+
+    if (next) {
   next->s_fence->scheduled.timestamp =
   job->s_fence->finished.timestamp;
-
+    /* start TO timer for next job */
+    drm_sched_start_timeout(sched);
+    }
   } else {
   job = NULL;
-    /* queue timeout for next job */
-    drm_sched_start_timeout(sched);
   }
     spin_unlock(>job_list_lock);

Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

2021-08-27 Thread Christian König

Yes, I don't see any good reason for that either.

Christian.

Am 27.08.21 um 15:45 schrieb Andrey Grodzovsky:

So we agree if (kthread_should_park()) return NULL should go away ?

Andrey


On 2021-08-27 3:46 a.m., Liu, Monk wrote:

[AMD Official Use Only]

Yeah, that "kthread_should_park" is also irrelevant looks to me as 
well and it delays the signaled job's cleanup/free


Thanks

--
Monk Liu | Cloud-GPU Core team
--

-Original Message-
From: Christian König 
Sent: Friday, August 27, 2021 2:12 PM
To: Grodzovsky, Andrey ; Liu, Monk 
; amd-...@lists.freedesktop.org; Koenig, Christian 


Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

I don't think that this will be necessary nor desired.

See the job should be cleaned up as soon as possible after it is 
finished or otherwise we won't cancel the timeout quick enough either.


Christian.

Am 26.08.21 um 22:14 schrieb Andrey Grodzovsky:

Attached quick patch for per job TTL calculation to make more precises
next timer expiration. It's on top of the patch in this thread. Let me
know if this makes sense.

Andrey

On 2021-08-26 10:03 a.m., Andrey Grodzovsky wrote:

On 2021-08-26 12:55 a.m., Monk Liu wrote:

issue:
in cleanup_job the cancle_delayed_work will cancel a TO timer even
the its corresponding job is still running.

fix:
do not cancel the timer in cleanup_job, instead do the cancelling
only when the heading job is signaled, and if there is a "next" job
we start_timeout again.

v2:
further cleanup the logic, and do the TDR timer cancelling if the
signaled job is the last one in its scheduler.

v3:
change the issue description
remove the cancel_delayed_work in the begining of the cleanup_job
recover the implement of drm_sched_job_begin.

TODO:
1)introduce pause/resume scheduler in job_timeout to serial the
handling of scheduler and job_timeout.
2)drop the bad job's del and insert in scheduler due to above
serialization (no race issue anymore with the serialization)

Signed-off-by: Monk Liu 
---
   drivers/gpu/drm/scheduler/sched_main.c | 25
++---
   1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c
b/drivers/gpu/drm/scheduler/sched_main.c
index a2a9536..ecf8140 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -676,13 +676,7 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   {
   struct drm_sched_job *job, *next;
   -    /*
- * Don't destroy jobs while the timeout worker is running OR
thread
- * is being parked and hence assumed to not touch pending_list
- */
-    if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
-    !cancel_delayed_work(>work_tdr)) ||
-    kthread_should_park())
+    if (kthread_should_park())
   return NULL;


I actually don't see why we need to keep the above, on the other side
(in drm_sched_stop) we won't touch the pending list anyway until
sched thread came to full stop (kthread_park). If you do see a reason
why this needed then a comment should be here i think.

Andrey



spin_lock(>job_list_lock);
@@ -693,17 +687,21 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   if (job && dma_fence_is_signaled(>s_fence->finished)) {
   /* remove job from pending_list */
   list_del_init(>list);
+
+    /* cancel this job's TO timer */
+    cancel_delayed_work(>work_tdr);
   /* make the scheduled timestamp more accurate */
   next = list_first_entry_or_null(>pending_list,
   typeof(*next), list);
-    if (next)
+
+    if (next) {
   next->s_fence->scheduled.timestamp =
   job->s_fence->finished.timestamp;
-
+    /* start TO timer for next job */
+    drm_sched_start_timeout(sched);
+    }
   } else {
   job = NULL;
-    /* queue timeout for next job */
-    drm_sched_start_timeout(sched);
   }
     spin_unlock(>job_list_lock);
@@ -791,11 +789,8 @@ static int drm_sched_main(void *param)
 (entity = drm_sched_select_entity(sched)))
||
    kthread_should_stop());
   -    if (cleanup_job) {
+    if (cleanup_job)
   sched->ops->free_job(cleanup_job);
-    /* queue timeout for next job */
-    drm_sched_start_timeout(sched);
-    }
     if (!entity)
   continue;




DE2.0 YV12 playback issues after ea067aee45a8

2021-08-27 Thread Roman Stratiienko
Hello Jernej,

During local testing I faced an issue where YV12 buffers are displayed
all in blue.

Issue can be fixed by reverting:
ea067aee45a8 ("drm/sun4i: de2/de3: Remove redundant CSC matrices")

Could you have a look please?

Best regards,
Roman Stratiienko


Re: DE2.0 YV12 playback issues after ea067aee45a8

2021-08-27 Thread Roman Stratiienko
+CC: jernej.skra...@gmail.com

пт, 27 авг. 2021 г. в 16:12, Roman Stratiienko :
>
> Hello Jernej,
>
> During local testing I faced an issue where YV12 buffers are displayed
> all in blue.
>
> Issue can be fixed by reverting:
> ea067aee45a8 ("drm/sun4i: de2/de3: Remove redundant CSC matrices")
>
> Could you have a look please?
>
> Best regards,
> Roman Stratiienko


Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

2021-08-27 Thread Andrey Grodzovsky

So we agree if (kthread_should_park()) return NULL should go away ?

Andrey


On 2021-08-27 3:46 a.m., Liu, Monk wrote:

[AMD Official Use Only]

Yeah, that "kthread_should_park" is also irrelevant looks to me as well and it 
delays the signaled job's cleanup/free

Thanks

--
Monk Liu | Cloud-GPU Core team
--

-Original Message-
From: Christian König 
Sent: Friday, August 27, 2021 2:12 PM
To: Grodzovsky, Andrey ; Liu, Monk ; 
amd-...@lists.freedesktop.org; Koenig, Christian 
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

I don't think that this will be necessary nor desired.

See the job should be cleaned up as soon as possible after it is finished or 
otherwise we won't cancel the timeout quick enough either.

Christian.

Am 26.08.21 um 22:14 schrieb Andrey Grodzovsky:

Attached quick patch for per job TTL calculation to make more precises
next timer expiration. It's on top of the patch in this thread. Let me
know if this makes sense.

Andrey

On 2021-08-26 10:03 a.m., Andrey Grodzovsky wrote:

On 2021-08-26 12:55 a.m., Monk Liu wrote:

issue:
in cleanup_job the cancle_delayed_work will cancel a TO timer even
the its corresponding job is still running.

fix:
do not cancel the timer in cleanup_job, instead do the cancelling
only when the heading job is signaled, and if there is a "next" job
we start_timeout again.

v2:
further cleanup the logic, and do the TDR timer cancelling if the
signaled job is the last one in its scheduler.

v3:
change the issue description
remove the cancel_delayed_work in the begining of the cleanup_job
recover the implement of drm_sched_job_begin.

TODO:
1)introduce pause/resume scheduler in job_timeout to serial the
handling of scheduler and job_timeout.
2)drop the bad job's del and insert in scheduler due to above
serialization (no race issue anymore with the serialization)

Signed-off-by: Monk Liu 
---
   drivers/gpu/drm/scheduler/sched_main.c | 25
++---
   1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c
b/drivers/gpu/drm/scheduler/sched_main.c
index a2a9536..ecf8140 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -676,13 +676,7 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   {
   struct drm_sched_job *job, *next;
   -    /*
- * Don't destroy jobs while the timeout worker is running OR
thread
- * is being parked and hence assumed to not touch pending_list
- */
-    if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
-    !cancel_delayed_work(>work_tdr)) ||
-    kthread_should_park())
+    if (kthread_should_park())
   return NULL;


I actually don't see why we need to keep the above, on the other side
(in drm_sched_stop) we won't touch the pending list anyway until
sched thread came to full stop (kthread_park). If you do see a reason
why this needed then a comment should be here i think.

Andrey



spin_lock(>job_list_lock);
@@ -693,17 +687,21 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   if (job && dma_fence_is_signaled(>s_fence->finished)) {
   /* remove job from pending_list */
   list_del_init(>list);
+
+    /* cancel this job's TO timer */
+    cancel_delayed_work(>work_tdr);
   /* make the scheduled timestamp more accurate */
   next = list_first_entry_or_null(>pending_list,
   typeof(*next), list);
-    if (next)
+
+    if (next) {
   next->s_fence->scheduled.timestamp =
   job->s_fence->finished.timestamp;
-
+    /* start TO timer for next job */
+    drm_sched_start_timeout(sched);
+    }
   } else {
   job = NULL;
-    /* queue timeout for next job */
-    drm_sched_start_timeout(sched);
   }
     spin_unlock(>job_list_lock);
@@ -791,11 +789,8 @@ static int drm_sched_main(void *param)
     (entity = drm_sched_select_entity(sched)))
||
    kthread_should_stop());
   -    if (cleanup_job) {
+    if (cleanup_job)
   sched->ops->free_job(cleanup_job);
-    /* queue timeout for next job */
-    drm_sched_start_timeout(sched);
-    }
     if (!entity)
   continue;


Re: [PATCH libdrm 19/25] tests: tegra: Add VIC 3.0 support

2021-08-27 Thread Michał Mirosław
On Fri, Aug 27, 2021 at 03:22:59PM +0200, Thierry Reding wrote:
> From: Thierry Reding 
> 
> The Video Image Composer (VIC) 3.0 can be found on NVIDIA Tegra124 SoCs.a
[...]
> +static int vic30_clear(struct vic *v, struct vic_image *output,
> +   unsigned int alpha, unsigned int red,
> +   unsigned int green, unsigned int blue)
> +{
> +struct vic30 *vic = container_of(v, struct vic30, base);
> +ConfigStruct *c;
> +int err;
> +
> +err = drm_tegra_bo_map(vic->config.bo, (void **));
> +if (err < 0) {
> +fprintf(stderr, "failed to map configuration structure: %s\n",
> +strerror(-err));
> +return err;
> +}
> +
> +memset(c, 0, sizeof(*c));
> +
> +c->surfaceList0Struct.TargetRectLeft = 0;
> +c->surfaceList0Struct.TargetRectTop = 0;
> +c->surfaceList0Struct.TargetRectRight = output->width - 1;
> +c->surfaceList0Struct.TargetRectBottom = output->height - 1;
> +
> +c->blending0Struct.PixelFormat = output->format;
> +c->blending0Struct.BackgroundAlpha = alpha;
> +c->blending0Struct.BackgroundR = red;
> +c->blending0Struct.BackgroundG = green;
> +c->blending0Struct.BackgroundB = blue;
> +c->blending0Struct.LumaWidth = output->stride - 1;
> +c->blending0Struct.LumaHeight = output->height - 1;
> +c->blending0Struct.ChromaWidth = 16383;
> +c->blending0Struct.ChromaHeight = 16383;
> +c->blending0Struct.TargetRectLeft = 0;
> +c->blending0Struct.TargetRectTop = 0;
> +c->blending0Struct.TargetRectRight = output->width - 1;
> +c->blending0Struct.TargetRectBottom = output->height - 1;
> +c->blending0Struct.SurfaceWidth = output->width - 1;
> +c->blending0Struct.SurfaceHeight = output->height - 1;
> +c->blending0Struct.BlkKind = output->kind;
> +c->blending0Struct.BlkHeight = 0;
> +
> +c->fetchControl0Struct.TargetRectLeft = 0;
> +c->fetchControl0Struct.TargetRectTop = 0;
> +c->fetchControl0Struct.TargetRectRight = output->width - 1;
> +c->fetchControl0Struct.TargetRectBottom = output->height - 1;
> +
> +drm_tegra_bo_unmap(vic->config.bo);
> +
> +return 0;
> +}
[...]

It does look exactly like:

return vic30_fill(v, output, 0, 0, output->width - 1,
output->height - 1, alpha, red, green, blue);

Best Regards
Michał Mirosław


Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

2021-08-27 Thread Andrey Grodzovsky
The TS  represents the point in time when the job was inserted into the 
pending list.
I don't think it matters when it actually starts to be processed, what 
matters is when this job was inserted into pending list because right at 
that point you arm the TO timer (when no other is running already)
and so when the previous job completes and you cancel and rearm again 
you can use that TS from the next job in pending list to calculate how 
much time has actually left for it to run before TDR must be initiated
and not just give it again full TO value to run even if it has already 
been running for a while.


Also, i am not sure also about the assumption that what we measure is 
processing by HW, what we measure is from the moment it was scheduled to 
ring to the moment the job completed (EOP event). At least that what our 
TDR timer measures and so it makes sense to set the TS at this point.


Andrey

On 2021-08-27 3:20 a.m., Liu, Monk wrote:

[AMD Official Use Only]

what is that 'ts' representing for ? it looks to me the jiffies that it get 
scheduled to the ring,  but a job scheduled to the ring doesn't represent it's 
being processed by hw.

Thanks

--
Monk Liu | Cloud-GPU Core team
--

-Original Message-
From: Grodzovsky, Andrey 
Sent: Friday, August 27, 2021 4:14 AM
To: Liu, Monk ; amd-...@lists.freedesktop.org; Koenig, Christian 

Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/sched: fix the bug of time out calculation(v3)

Attached quick patch for per job TTL calculation to make more precises next 
timer expiration. It's on top of the patch in this thread. Let me know if this 
makes sense.

Andrey

On 2021-08-26 10:03 a.m., Andrey Grodzovsky wrote:

On 2021-08-26 12:55 a.m., Monk Liu wrote:

issue:
in cleanup_job the cancle_delayed_work will cancel a TO timer even
the its corresponding job is still running.

fix:
do not cancel the timer in cleanup_job, instead do the cancelling
only when the heading job is signaled, and if there is a "next" job
we start_timeout again.

v2:
further cleanup the logic, and do the TDR timer cancelling if the
signaled job is the last one in its scheduler.

v3:
change the issue description
remove the cancel_delayed_work in the begining of the cleanup_job
recover the implement of drm_sched_job_begin.

TODO:
1)introduce pause/resume scheduler in job_timeout to serial the
handling of scheduler and job_timeout.
2)drop the bad job's del and insert in scheduler due to above
serialization (no race issue anymore with the serialization)

Signed-off-by: Monk Liu 
---
   drivers/gpu/drm/scheduler/sched_main.c | 25
++---
   1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c
b/drivers/gpu/drm/scheduler/sched_main.c
index a2a9536..ecf8140 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -676,13 +676,7 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   {
   struct drm_sched_job *job, *next;
   -    /*
- * Don't destroy jobs while the timeout worker is running OR
thread
- * is being parked and hence assumed to not touch pending_list
- */
-    if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
-    !cancel_delayed_work(>work_tdr)) ||
-    kthread_should_park())
+    if (kthread_should_park())
   return NULL;


I actually don't see why we need to keep the above, on the other side
(in drm_sched_stop) we won't touch the pending list anyway until sched
thread came to full stop (kthread_park). If you do see a reason why
this needed then a comment should be here i think.

Andrey



spin_lock(>job_list_lock);
@@ -693,17 +687,21 @@ drm_sched_get_cleanup_job(struct
drm_gpu_scheduler *sched)
   if (job && dma_fence_is_signaled(>s_fence->finished)) {
   /* remove job from pending_list */
   list_del_init(>list);
+
+    /* cancel this job's TO timer */
+    cancel_delayed_work(>work_tdr);
   /* make the scheduled timestamp more accurate */
   next = list_first_entry_or_null(>pending_list,
   typeof(*next), list);
-    if (next)
+
+    if (next) {
   next->s_fence->scheduled.timestamp =
   job->s_fence->finished.timestamp;
-
+    /* start TO timer for next job */
+    drm_sched_start_timeout(sched);
+    }
   } else {
   job = NULL;
-    /* queue timeout for next job */
-    drm_sched_start_timeout(sched);
   }
     spin_unlock(>job_list_lock);
@@ -791,11 +789,8 @@ static int drm_sched_main(void *param)
     (entity = drm_sched_select_entity(sched))) ||
    kthread_should_stop());
   -    if (cleanup_job) {
+    if (cleanup_job)
   sched->ops->free_job(cleanup_job);
-    /* queue timeout for next job */
-    

TTM tt size larger than buffer object?

2021-08-27 Thread Thomas Hellström

Hi, Christian.

We have a use-case with i915 where the data representation of a buffer 
object is larger in system memory than in LMEM/VRAM. Hence we'd like to 
create a ttm_tt that is larger than the buffer object itself. Quickly 
auditing the TTM code it looks like that should be pretty safe, as 
ttm->num_pages is not really much accessed outside the tt code and the 
pool code where we're doing the right thing.


The additional data will really only be accessed by the blitter so when 
cpu-mapping, mapping just the original buffer object size is correct. 
However with swapping the additional data needs to be swapped out and 
the code is doing that correctly as well.


Do you think this is an acceptable solution?

/Thomas




[PATCH] drm/i915: Handle Intel igfx + Intel dgfx hybrid graphics setup

2021-08-27 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

In short this makes i915 work for hybrid setups (DRI_PRIME=1 with Mesa)
when rendering is done on Intel dgfx and scanout/composition on Intel
igfx.

Before this patch the driver was not quite ready for that setup, mainly
because it was able to emit a semaphore wait between the two GPUs, which
results in deadlocks because semaphore target location in HWSP is neither
shared between the two, nor mapped in both GGTT spaces.

To fix it the patch adds an additional check to a couple of relevant code
paths in order to prevent using semaphores for inter-engine
synchronisation between different driver instances.

Patch also moves singly used i915_gem_object_last_write_engine to be
private in its only calling unit (debugfs), while modifying it to only
show activity belonging to the respective driver instance.

What remains in this problem space is the question of the GEM busy ioctl.
We have a somewhat ambigous comment there saying only status of native
fences will be reported, which could be interpreted as either i915, or
native to the drm fd. For now I have decided to leave that as is, meaning
any i915 instance activity continues to be reported.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.h | 17 
 drivers/gpu/drm/i915/i915_debugfs.c| 23 +-
 drivers/gpu/drm/i915/i915_request.c|  7 ++-
 drivers/gpu/drm/i915/i915_request.h|  1 +
 4 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 48112b9d76df..3043fcbd31bd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -503,23 +503,6 @@ i915_gem_object_finish_access(struct drm_i915_gem_object 
*obj)
i915_gem_object_unpin_pages(obj);
 }
 
-static inline struct intel_engine_cs *
-i915_gem_object_last_write_engine(struct drm_i915_gem_object *obj)
-{
-   struct intel_engine_cs *engine = NULL;
-   struct dma_fence *fence;
-
-   rcu_read_lock();
-   fence = dma_resv_get_excl_unlocked(obj->base.resv);
-   rcu_read_unlock();
-
-   if (fence && dma_fence_is_i915(fence) && !dma_fence_is_signaled(fence))
-   engine = to_request(fence)->engine;
-   dma_fence_put(fence);
-
-   return engine;
-}
-
 void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
 unsigned int cache_level);
 void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 04351a851586..2f49ff0e8c21 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -135,6 +135,27 @@ static const char *stringify_vma_type(const struct 
i915_vma *vma)
return "ppgtt";
 }
 
+static struct intel_engine_cs *
+last_write_engine(struct drm_i915_private *i915,
+ struct drm_i915_gem_object *obj)
+{
+   struct intel_engine_cs *engine = NULL;
+   struct dma_fence *fence;
+
+   rcu_read_lock();
+   fence = dma_resv_get_excl_unlocked(obj->base.resv);
+   rcu_read_unlock();
+
+   if (fence &&
+   !dma_fence_is_signaled(fence) &&
+   dma_fence_is_i915(fence) &&
+   to_request(fence)->i915 == i915)
+   engine = to_request(fence)->engine;
+   dma_fence_put(fence);
+
+   return engine;
+}
+
 void
 i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 {
@@ -230,7 +251,7 @@ i915_debugfs_describe_obj(struct seq_file *m, struct 
drm_i915_gem_object *obj)
if (i915_gem_object_is_framebuffer(obj))
seq_printf(m, " (fb)");
 
-   engine = i915_gem_object_last_write_engine(obj);
+   engine = last_write_engine(dev_priv, obj);
if (engine)
seq_printf(m, " (%s)", engine->name);
 }
diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index ce446716d092..d2dec669d262 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -900,6 +900,7 @@ __i915_request_create(struct intel_context *ce, gfp_t gfp)
 * hold the intel_context reference. In execlist mode the request always
 * eventually points to a physical engine so this isn't an issue.
 */
+   rq->i915 = tl->gt->i915;
rq->context = intel_context_get(ce);
rq->engine = ce->engine;
rq->ring = ce->ring;
@@ -1160,6 +1161,9 @@ emit_semaphore_wait(struct i915_request *to,
const intel_engine_mask_t mask = READ_ONCE(from->engine)->mask;
struct i915_sw_fence *wait = >submit;
 
+   if (to->i915 != from->i915)
+   goto await_fence;
+
if (!intel_context_use_semaphores(to->context))
goto await_fence;
 
@@ -1263,7 +1267,8 @@ __i915_request_await_execution(struct 

[PATCH libdrm 24/25] tests: tegra: Add VIC blit test

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

This test will attempt to use the VIC to blit from one surface to
another.

Signed-off-by: Thierry Reding 
---
 tests/tegra/meson.build |   9 ++
 tests/tegra/vic-blit.c  | 333 
 2 files changed, 342 insertions(+)
 create mode 100644 tests/tegra/vic-blit.c

diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index e44bd3a4393d..a9ca09e12f3e 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -91,3 +91,12 @@ vic_clear = executable(
   link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra],
   install : with_install_tests,
 )
+
+vic_blit = executable(
+  'tegra-vic-blit',
+  files('vic-blit.c'),
+  include_directories : [inc_root, inc_drm, inc_tegra],
+  c_args : warn_c_args,
+  link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra],
+  install : with_install_tests,
+)
diff --git a/tests/tegra/vic-blit.c b/tests/tegra/vic-blit.c
new file mode 100644
index ..1b4a3eff87d3
--- /dev/null
+++ b/tests/tegra/vic-blit.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tegra.h"
+
+#include "host1x.h"
+#include "vic.h"
+
+/* clear output image to red */
+static int clear(struct vic *vic, struct drm_tegra_channel *channel,
+ struct vic_image *output)
+{
+struct drm_tegra_pushbuf *pushbuf;
+struct drm_tegra_job *job;
+uint32_t *ptr;
+int err;
+
+err = drm_tegra_job_new(channel, );
+if (err < 0) {
+fprintf(stderr, "failed to create job: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_job_get_pushbuf(job, );
+if (err < 0) {
+fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
+return 1;
+}
+
+err = vic->ops->clear(vic, output, 1023, 1023, 0, 0);
+if (err < 0) {
+fprintf(stderr, "failed to clear surface: %s\n", strerror(-err));
+return err;
+}
+
+err = drm_tegra_pushbuf_begin(pushbuf, 32, );
+if (err < 0) {
+fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err));
+return err;
+}
+
+err = vic->ops->execute(vic, pushbuf, , output, NULL, 0);
+if (err < 0) {
+fprintf(stderr, "failed to execute operation: %s\n", strerror(-err));
+return err;
+}
+
+err = drm_tegra_pushbuf_sync_cond(pushbuf, , vic->syncpt,
+  DRM_TEGRA_SYNC_COND_OP_DONE);
+if (err < 0) {
+fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err));
+return err;
+}
+
+err = drm_tegra_pushbuf_end(pushbuf, ptr);
+if (err < 0) {
+fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err));
+return err;
+}
+
+err = drm_tegra_job_submit(job, NULL);
+if (err < 0) {
+fprintf(stderr, "failed to submit job: %s\n", strerror(-err));
+return err;
+}
+
+err = drm_tegra_job_wait(job, 10);
+if (err < 0) {
+fprintf(stderr, "failed to wait for job: %s\n", strerror(-err));
+return err;
+}
+
+drm_tegra_job_free(job);
+
+return 0;
+}
+
+/* fill bottom half of image to blue */
+static int fill(struct vic *vic, struct drm_tegra_channel *channel,
+struct vic_image *output)
+{
+struct drm_tegra_pushbuf *pushbuf;
+struct drm_tegra_job *job;
+uint32_t *ptr;
+int err;
+
+err = drm_tegra_job_new(channel, );
+if (err < 0) {
+fprintf(stderr, "failed to create job: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_job_get_pushbuf(job, );
+if (err < 0) {
+fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_pushbuf_begin(pushbuf, 32, );
+if (err < 0) {
+

[PATCH libdrm 21/25] tests: tegra: Add VIC 4.1 support

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

The Video Image Composer (VIC) 4.1 can be found on NVIDIA Tegra186 SoCs.
It uses a different class (B1B6) that is slightly incompatible with the
class found on earlier generations.

Signed-off-by: Thierry Reding 
---
 tests/tegra/meson.build |   2 +
 tests/tegra/vic.c   |   7 +
 tests/tegra/vic41.c | 416 
 tests/tegra/vic41.h | 372 +++
 4 files changed, 797 insertions(+)
 create mode 100644 tests/tegra/vic41.c
 create mode 100644 tests/tegra/vic41.h

diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index e0f94891a76f..ad5d38bcd8dc 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -38,6 +38,8 @@ libdrm_test_tegra = static_library(
 'vic30.h',
 'vic40.c',
 'vic40.h',
+'vic41.c',
+'vic41.h',
   ), config_file ],
   include_directories : [inc_root, inc_drm, inc_tegra],
   link_with : libdrm,
diff --git a/tests/tegra/vic.c b/tests/tegra/vic.c
index 8acca30b6e6b..9403a46a7050 100644
--- a/tests/tegra/vic.c
+++ b/tests/tegra/vic.c
@@ -138,6 +138,10 @@ int vic30_new(struct drm_tegra *drm, struct 
drm_tegra_channel *channel,
 int vic40_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
   struct vic **vicp);
 
+/* from vic41.c */
+int vic41_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
+  struct vic **vicp);
+
 int vic_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
 struct vic **vicp)
 {
@@ -151,6 +155,9 @@ int vic_new(struct drm_tegra *drm, struct drm_tegra_channel 
*channel,
 
 case 0x21:
 return vic40_new(drm, channel, vicp);
+
+case 0x18:
+return vic41_new(drm, channel, vicp);
 }
 
 return -ENOTSUP;
diff --git a/tests/tegra/vic41.c b/tests/tegra/vic41.c
new file mode 100644
index ..26cae1a895c3
--- /dev/null
+++ b/tests/tegra/vic41.c
@@ -0,0 +1,416 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+
+#include "private.h"
+#include "tegra.h"
+#include "vic.h"
+#include "vic41.h"
+
+struct vic41 {
+struct vic base;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} config;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} filter;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} hist;
+};
+
+static int vic41_clear(struct vic *v, struct vic_image *output,
+   unsigned int alpha, unsigned int red,
+   unsigned int green, unsigned int blue)
+{
+struct vic41 *vic = container_of(v, struct vic41, base);
+ConfigStruct *c;
+int err;
+
+err = drm_tegra_bo_map(vic->config.bo, (void **));
+if (err < 0) {
+fprintf(stderr, "failed to map configuration structure: %s\n",
+strerror(-err));
+return err;
+}
+
+memset(c, 0, sizeof(*c));
+
+c->outputConfig.TargetRectTop = 0;
+c->outputConfig.TargetRectLeft = 0;
+c->outputConfig.TargetRectRight = output->width - 1;
+c->outputConfig.TargetRectBottom = output->height - 1;
+c->outputConfig.BackgroundAlpha = alpha;
+c->outputConfig.BackgroundR = red;
+c->outputConfig.BackgroundG = green;
+c->outputConfig.BackgroundB = blue;
+
+c->outputSurfaceConfig.OutPixelFormat = output->format;
+c->outputSurfaceConfig.OutBlkKind = output->kind;
+c->outputSurfaceConfig.OutBlkHeight = 0;
+c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1;
+c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1;
+c->outputSurfaceConfig.OutLumaWidth = output->stride - 1;
+c->outputSurfaceConfig.OutLumaHeight = output->height - 1;
+c->outputSurfaceConfig.OutChromaWidth = 16383;
+c->outputSurfaceConfig.OutChromaHeight = 

[PATCH libdrm 20/25] tests: tegra: Add VIC 4.0 support

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

The Video Image Composer (VIC) 4.0 can be found on NVIDIA Tegra210 SoCs.
It uses a different class (B0B6) that is slightly incompatible with the
class found on earlier generations.

Signed-off-by: Thierry Reding 
---
 tests/tegra/meson.build |   2 +
 tests/tegra/vic.c   |   7 +
 tests/tegra/vic40.c | 412 
 tests/tegra/vic40.h | 285 +++
 4 files changed, 706 insertions(+)
 create mode 100644 tests/tegra/vic40.c
 create mode 100644 tests/tegra/vic40.h

diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index 934b728a48d9..e0f94891a76f 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -36,6 +36,8 @@ libdrm_test_tegra = static_library(
 'vic.h',
 'vic30.c',
 'vic30.h',
+'vic40.c',
+'vic40.h',
   ), config_file ],
   include_directories : [inc_root, inc_drm, inc_tegra],
   link_with : libdrm,
diff --git a/tests/tegra/vic.c b/tests/tegra/vic.c
index 6001a0cdb9d2..8acca30b6e6b 100644
--- a/tests/tegra/vic.c
+++ b/tests/tegra/vic.c
@@ -134,6 +134,10 @@ void vic_image_dump(struct vic_image *image, FILE *fp)
 int vic30_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
   struct vic **vicp);
 
+/* from vic40.c */
+int vic40_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
+  struct vic **vicp);
+
 int vic_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
 struct vic **vicp)
 {
@@ -144,6 +148,9 @@ int vic_new(struct drm_tegra *drm, struct drm_tegra_channel 
*channel,
 switch (version) {
 case 0x40:
 return vic30_new(drm, channel, vicp);
+
+case 0x21:
+return vic40_new(drm, channel, vicp);
 }
 
 return -ENOTSUP;
diff --git a/tests/tegra/vic40.c b/tests/tegra/vic40.c
new file mode 100644
index ..2809b9c7f5d0
--- /dev/null
+++ b/tests/tegra/vic40.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+
+#include "private.h"
+#include "tegra.h"
+#include "vic.h"
+#include "vic40.h"
+
+struct vic40 {
+struct vic base;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} config;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} filter;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} hist;
+};
+
+static int vic40_clear(struct vic *v, struct vic_image *output,
+   unsigned int alpha, unsigned int red,
+   unsigned int green, unsigned int blue)
+{
+struct vic40 *vic = container_of(v, struct vic40, base);
+ConfigStruct *c;
+int err;
+
+err = drm_tegra_bo_map(vic->config.bo, (void **));
+if (err < 0) {
+fprintf(stderr, "failed to map configuration structure: %s\n",
+strerror(-err));
+return err;
+}
+
+memset(c, 0, sizeof(*c));
+
+c->outputConfig.TargetRectTop = 0;
+c->outputConfig.TargetRectLeft = 0;
+c->outputConfig.TargetRectRight = output->width - 1;
+c->outputConfig.TargetRectBottom = output->height - 1;
+c->outputConfig.BackgroundAlpha = alpha;
+c->outputConfig.BackgroundR = red;
+c->outputConfig.BackgroundG = green;
+c->outputConfig.BackgroundB = blue;
+
+c->outputSurfaceConfig.OutPixelFormat = output->format;
+c->outputSurfaceConfig.OutBlkKind = output->kind;
+c->outputSurfaceConfig.OutBlkHeight = 0;
+c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1;
+c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1;
+c->outputSurfaceConfig.OutLumaWidth = output->stride - 1;
+c->outputSurfaceConfig.OutLumaHeight = output->height - 1;
+c->outputSurfaceConfig.OutChromaWidth = 16383;
+c->outputSurfaceConfig.OutChromaHeight = 16383;

[PATCH libdrm 23/25] tests: tegra: Add VIC clear test

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

This test will attempt to use VIC to clear a surface.

Signed-off-by: Thierry Reding 
---
 tests/tegra/meson.build |   9 +++
 tests/tegra/vic-clear.c | 173 
 2 files changed, 182 insertions(+)
 create mode 100644 tests/tegra/vic-clear.c

diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index d71d3d564efe..e44bd3a4393d 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -82,3 +82,12 @@ syncpt_timeout = executable(
   link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra],
   install : with_install_tests,
 )
+
+vic_clear = executable(
+  'tegra-vic-clear',
+  files('vic-clear.c'),
+  include_directories : [inc_root, inc_drm, inc_tegra],
+  c_args : warn_c_args,
+  link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra],
+  install : with_install_tests,
+)
diff --git a/tests/tegra/vic-clear.c b/tests/tegra/vic-clear.c
new file mode 100644
index ..f65a644d398c
--- /dev/null
+++ b/tests/tegra/vic-clear.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "util_math.h"
+
+#include "tegra.h"
+
+#include "host1x.h"
+#include "vic.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+int main(int argc, char *argv[])
+{
+const unsigned int format = VIC_PIXEL_FORMAT_A8R8G8B8;
+const unsigned int kind = VIC_BLK_KIND_PITCH;
+const unsigned int width = 16, height = 16;
+const char *device = "/dev/dri/renderD128";
+struct drm_tegra_channel *channel;
+struct drm_tegra_pushbuf *pushbuf;
+struct drm_tegra_job *job;
+struct vic_image *output;
+struct drm_tegra *drm;
+unsigned int version;
+struct vic *vic;
+uint32_t *pb;
+int fd, err;
+void *ptr;
+
+if (argc > 1)
+device = argv[1];
+
+fd = open(device, O_RDWR);
+if (fd < 0) {
+fprintf(stderr, "open() failed: %s\n", strerror(errno));
+return 1;
+}
+
+err = drm_tegra_new(fd, );
+if (err < 0) {
+fprintf(stderr, "failed to open Tegra device: %s\n", strerror(-err));
+close(fd);
+return 1;
+}
+
+err = drm_tegra_channel_open(drm, DRM_TEGRA_VIC, );
+if (err < 0) {
+fprintf(stderr, "failed to open channel to VIC: %s\n", strerror(-err));
+return 1;
+}
+
+version = drm_tegra_channel_get_version(channel);
+printf("version: %08x\n", version);
+
+err = vic_new(drm, channel, );
+if (err < 0) {
+fprintf(stderr, "failed to create VIC: %s\n", strerror(-err));
+return 1;
+}
+
+err = vic_image_new(vic, width, height, format, kind, 
DRM_TEGRA_CHANNEL_MAP_READ_WRITE,
+);
+if (err < 0) {
+fprintf(stderr, "failed to create output image: %d\n", err);
+return 1;
+}
+
+printf("image: %zu bytes\n", output->size);
+
+err = drm_tegra_bo_map(output->bo, );
+if (err < 0) {
+fprintf(stderr, "failed to map output image: %d\n", err);
+return 1;
+}
+
+memset(ptr, 0xff, output->size);
+drm_tegra_bo_unmap(output->bo);
+
+printf("output: %ux%u\n", output->width, output->height);
+vic_image_dump(output, stdout);
+
+err = drm_tegra_job_new(channel, );
+if (err < 0) {
+fprintf(stderr, "failed to create job: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_job_get_pushbuf(job, );
+if (err < 0) {
+fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_pushbuf_begin(pushbuf, 32, );
+if (err < 0) {
+fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err));
+return 1;
+}
+
+err = vic->ops->clear(vic, output, 1023, 0, 0, 1023);
+if (err < 0) {
+fprintf(stderr, "failed 

[PATCH libdrm 11/25] tegra: Add channel APIs

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

These new functions can be used to open a channel to a given engine, map
and unmap buffer objects to that channel, and close the channel.

Signed-off-by: Thierry Reding 
---
 tegra/channel.c | 195 
 tegra/meson.build   |   2 +-
 tegra/private.h |  24 +
 tegra/tegra-symbols.txt |   5 ++
 tegra/tegra.h   |  22 +
 5 files changed, 247 insertions(+), 1 deletion(-)
 create mode 100644 tegra/channel.c

diff --git a/tegra/channel.c b/tegra/channel.c
new file mode 100644
index ..391362023259
--- /dev/null
+++ b/tegra/channel.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright © 2012, 2013 Thierry Reding
+ * Copyright © 2013 Erik Faye-Lund
+ * Copyright © 2014-2021 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include 
+#include 
+
+#include 
+
+#include "private.h"
+
+drm_public int
+drm_tegra_channel_open(struct drm_tegra *drm,
+   enum drm_tegra_class client,
+   struct drm_tegra_channel **channelp)
+{
+struct drm_tegra_channel_open args;
+struct drm_tegra_channel *channel;
+enum host1x_class class;
+int err;
+
+switch (client) {
+case DRM_TEGRA_HOST1X:
+class = HOST1X_CLASS_HOST1X;
+break;
+
+case DRM_TEGRA_GR2D:
+class = HOST1X_CLASS_GR2D;
+break;
+
+case DRM_TEGRA_GR3D:
+class = HOST1X_CLASS_GR3D;
+break;
+
+case DRM_TEGRA_VIC:
+class = HOST1X_CLASS_VIC;
+break;
+
+default:
+return -EINVAL;
+}
+
+channel = calloc(1, sizeof(*channel));
+if (!channel)
+return -ENOMEM;
+
+channel->drm = drm;
+
+memset(, 0, sizeof(args));
+args.host1x_class = class;
+
+err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_OPEN, );
+if (err < 0) {
+free(channel);
+return -errno;
+}
+
+channel->context = args.context;
+channel->version = args.version;
+channel->capabilities = args.capabilities;
+channel->class = class;
+
+switch (channel->version) {
+case 0x20:
+case 0x30:
+case 0x35:
+case 0x40:
+case 0x21:
+channel->cond_shift = 8;
+break;
+
+case 0x18:
+case 0x19:
+channel->cond_shift = 10;
+break;
+
+default:
+return -ENOTSUP;
+}
+
+*channelp = channel;
+
+return 0;
+}
+
+drm_public int drm_tegra_channel_close(struct drm_tegra_channel *channel)
+{
+struct drm_tegra_channel_close args;
+struct drm_tegra *drm;
+int err;
+
+if (!channel)
+return -EINVAL;
+
+drm = channel->drm;
+
+memset(, 0, sizeof(args));
+args.context = channel->context;
+
+err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_CLOSE, );
+if (err < 0)
+return -errno;
+
+free(channel);
+
+return 0;
+}
+
+drm_public unsigned int
+drm_tegra_channel_get_version(struct drm_tegra_channel *channel)
+{
+return channel->version;
+}
+
+drm_public int
+drm_tegra_channel_map(struct drm_tegra_channel *channel,
+  struct drm_tegra_bo *bo, uint32_t flags,
+  struct drm_tegra_mapping **mapp)
+{
+struct drm_tegra *drm = channel->drm;
+struct drm_tegra_channel_map args;
+struct drm_tegra_mapping *map;
+int err;
+
+if (!drm || !bo || !mapp)
+return -EINVAL;
+
+map = calloc(1, sizeof(*map));
+if (!map)
+return -ENOMEM;
+
+memset(, 0, sizeof(args));
+args.context = channel->context;
+args.handle = bo->handle;
+args.flags = flags;
+
+err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_MAP, );
+if (err < 0) {
+free(map);
+return -errno;
+}
+
+map->channel = channel;
+map->id = args.mapping;
+*mapp = map;
+
+return 0;
+}
+
+drm_public int
+drm_tegra_channel_unmap(struct drm_tegra_mapping 

[PATCH libdrm 13/25] tegra: Add syncpoint APIs

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

These new functions can be used to allocate and free syncpoints, as well
as wait for a syncpoint threshold to be reached. Jobs can also be waited
on if a syncpoint was attached to them.

Signed-off-by: Thierry Reding 
---
 tegra/job.c |  23 +
 tegra/meson.build   |   2 +-
 tegra/private.h |   5 ++
 tegra/pushbuf.c |  48 +++
 tegra/syncpt.c  | 101 
 tegra/tegra-symbols.txt |   7 +++
 tegra/tegra.h   |  16 +++
 7 files changed, 201 insertions(+), 1 deletion(-)
 create mode 100644 tegra/syncpt.c

diff --git a/tegra/job.c b/tegra/job.c
index c8c94e131ef0..75a344f1dcc5 100644
--- a/tegra/job.c
+++ b/tegra/job.c
@@ -162,3 +162,26 @@ drm_tegra_job_submit(struct drm_tegra_job *job, struct 
drm_tegra_fence *fence)
 
 return 0;
 }
+
+drm_public int
+drm_tegra_job_wait(struct drm_tegra_job *job, unsigned long timeout)
+{
+struct drm_tegra_channel *channel = job->channel;
+struct drm_tegra *drm = channel->drm;
+struct drm_tegra_syncpoint_wait args;
+struct timespec ts;
+int err;
+
+clock_gettime(CLOCK_MONOTONIC, );
+
+memset(, 0, sizeof(args));
+args.timeout_ns = ts.tv_sec * 10 + ts.tv_nsec + timeout;
+args.id = job->syncpt.id;
+args.threshold = job->syncpt.fence;
+
+err = ioctl(drm->fd, DRM_IOCTL_TEGRA_SYNCPOINT_WAIT, );
+if (err < 0)
+return -errno;
+
+return 0;
+}
diff --git a/tegra/meson.build b/tegra/meson.build
index 38e43039837c..3059b2a57d56 100644
--- a/tegra/meson.build
+++ b/tegra/meson.build
@@ -22,7 +22,7 @@ libdrm_tegra = library(
   'drm_tegra',
   [
 files(
-  'channel.c', 'job.c', 'private.h', 'pushbuf.c', 'tegra.c'
+  'channel.c', 'job.c', 'private.h', 'pushbuf.c', 'syncpt.c', 'tegra.c'
 ),
 config_file
   ],
diff --git a/tegra/private.h b/tegra/private.h
index 970ee8ad66d4..f134f3ea2cea 100644
--- a/tegra/private.h
+++ b/tegra/private.h
@@ -104,4 +104,9 @@ struct drm_tegra_submit_cmd *
 drm_tegra_job_add_command(struct drm_tegra_job *job, uint32_t type,
   uint32_t flags);
 
+struct drm_tegra_syncpoint {
+struct drm_tegra *drm;
+uint32_t id;
+};
+
 #endif /* __DRM_TEGRA_PRIVATE_H__ */
diff --git a/tegra/pushbuf.c b/tegra/pushbuf.c
index 380a50a0..0c0212e127a7 100644
--- a/tegra/pushbuf.c
+++ b/tegra/pushbuf.c
@@ -101,6 +101,25 @@ drm_tegra_pushbuf_end(struct drm_tegra_pushbuf *pushbuf, 
uint32_t *ptr)
 return 0;
 }
 
+drm_public int
+drm_tegra_pushbuf_wait(struct drm_tegra_pushbuf *pushbuf,
+   struct drm_tegra_syncpoint *syncpt,
+   uint32_t value)
+{
+struct drm_tegra_submit_cmd *command;
+
+command = drm_tegra_job_add_command(pushbuf->job,
+DRM_TEGRA_SUBMIT_CMD_WAIT_SYNCPT,
+0);
+if (!command)
+return -ENOMEM;
+
+command->wait_syncpt.id = syncpt->id;
+command->wait_syncpt.value = value;
+
+return 0;
+}
+
 drm_public int
 drm_tegra_pushbuf_relocate(struct drm_tegra_pushbuf *pushbuf, uint32_t **ptrp,
struct drm_tegra_mapping *target,
@@ -134,3 +153,32 @@ drm_tegra_pushbuf_relocate(struct drm_tegra_pushbuf 
*pushbuf, uint32_t **ptrp,
 
 return 0;
 }
+
+drm_public int
+drm_tegra_pushbuf_sync(struct drm_tegra_pushbuf *pushbuf,
+   struct drm_tegra_syncpoint *syncpt,
+   unsigned int count)
+{
+struct drm_tegra_job *job = pushbuf->job;
+
+job->syncpt.increments += count;
+job->syncpt.id = syncpt->id;
+
+return 0;
+}
+
+drm_public int
+drm_tegra_pushbuf_sync_cond(struct drm_tegra_pushbuf *pushbuf, uint32_t **ptrp,
+struct drm_tegra_syncpoint *syncpt,
+enum drm_tegra_sync_cond cond)
+{
+struct drm_tegra_channel *channel = pushbuf->job->channel;
+
+if (cond >= DRM_TEGRA_SYNC_COND_MAX)
+return -EINVAL;
+
+*(*ptrp)++ = HOST1X_OPCODE_NONINCR(0x0, 0x1);
+*(*ptrp)++ = cond << channel->cond_shift | syncpt->id;
+
+return drm_tegra_pushbuf_sync(pushbuf, syncpt, 1);
+}
diff --git a/tegra/syncpt.c b/tegra/syncpt.c
new file mode 100644
index ..16014186fa30
--- /dev/null
+++ b/tegra/syncpt.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright © 2021 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial 

[PATCH libdrm 22/25] tests: tegra: Add VIC 4.2 support

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

The Video Image Composer (VIC) 4.2 can be found on NVIDIA Tegra194 SoCs.
It uses a different class (C5B6) that is slightly incompatible with the
class found on earlier generations, although it is backwards compatible
with the class implemented on Tegra186 (B1B6).

Signed-off-by: Thierry Reding 
---
 tests/tegra/meson.build |   2 +
 tests/tegra/vic.c   |   7 +
 tests/tegra/vic42.c | 423 
 tests/tegra/vic42.h | 597 
 4 files changed, 1029 insertions(+)
 create mode 100644 tests/tegra/vic42.c
 create mode 100644 tests/tegra/vic42.h

diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index ad5d38bcd8dc..d71d3d564efe 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -40,6 +40,8 @@ libdrm_test_tegra = static_library(
 'vic40.h',
 'vic41.c',
 'vic41.h',
+'vic42.c',
+'vic42.h',
   ), config_file ],
   include_directories : [inc_root, inc_drm, inc_tegra],
   link_with : libdrm,
diff --git a/tests/tegra/vic.c b/tests/tegra/vic.c
index 9403a46a7050..8e65eb96c316 100644
--- a/tests/tegra/vic.c
+++ b/tests/tegra/vic.c
@@ -142,6 +142,10 @@ int vic40_new(struct drm_tegra *drm, struct 
drm_tegra_channel *channel,
 int vic41_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
   struct vic **vicp);
 
+/* from vic42.c */
+int vic42_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
+  struct vic **vicp);
+
 int vic_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
 struct vic **vicp)
 {
@@ -158,6 +162,9 @@ int vic_new(struct drm_tegra *drm, struct drm_tegra_channel 
*channel,
 
 case 0x18:
 return vic41_new(drm, channel, vicp);
+
+case 0x19:
+return vic42_new(drm, channel, vicp);
 }
 
 return -ENOTSUP;
diff --git a/tests/tegra/vic42.c b/tests/tegra/vic42.c
new file mode 100644
index ..fec22ceb42a0
--- /dev/null
+++ b/tests/tegra/vic42.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+
+#include "private.h"
+#include "tegra.h"
+#include "vic.h"
+#include "vic42.h"
+
+struct vic42 {
+struct vic base;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} config;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} filter;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} hist;
+};
+
+static int vic42_clear(struct vic *v, struct vic_image *output,
+   unsigned int alpha, unsigned int red,
+   unsigned int green, unsigned int blue)
+{
+struct vic42 *vic = container_of(v, struct vic42, base);
+ConfigStruct *c;
+int err;
+
+err = drm_tegra_bo_map(vic->config.bo, (void **));
+if (err < 0) {
+fprintf(stderr, "failed to map configuration structure: %s\n",
+strerror(-err));
+return err;
+}
+
+memset(c, 0, sizeof(*c));
+
+c->outputConfig.TargetRectTop = 0;
+c->outputConfig.TargetRectLeft = 0;
+c->outputConfig.TargetRectRight = output->width - 1;
+c->outputConfig.TargetRectBottom = output->height - 1;
+c->outputConfig.BackgroundAlpha = alpha;
+c->outputConfig.BackgroundR = red;
+c->outputConfig.BackgroundG = green;
+c->outputConfig.BackgroundB = blue;
+
+c->outputSurfaceConfig.OutPixelFormat = output->format;
+c->outputSurfaceConfig.OutBlkKind = output->kind;
+c->outputSurfaceConfig.OutBlkHeight = 0;
+c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1;
+c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1;
+c->outputSurfaceConfig.OutLumaWidth = output->stride - 1;
+printf("OutLumaWidth: %u\n", c->outputSurfaceConfig.OutLumaWidth);
+

[PATCH libdrm 25/25] tests: tegra: Add VIC flip test

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

This test will attempt to use the VIC to blit one surface to another
and perform a vertical flip.

Signed-off-by: Thierry Reding 
---
 tests/tegra/meson.build |   9 ++
 tests/tegra/vic-flip.c  | 333 
 2 files changed, 342 insertions(+)
 create mode 100644 tests/tegra/vic-flip.c

diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index a9ca09e12f3e..d24053265c2f 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -100,3 +100,12 @@ vic_blit = executable(
   link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra],
   install : with_install_tests,
 )
+
+vic_flip = executable(
+  'tegra-vic-flip',
+  files('vic-flip.c'),
+  include_directories : [inc_root, inc_drm, inc_tegra],
+  c_args : warn_c_args,
+  link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra],
+  install : with_install_tests,
+)
diff --git a/tests/tegra/vic-flip.c b/tests/tegra/vic-flip.c
new file mode 100644
index ..2e32d6eb4324
--- /dev/null
+++ b/tests/tegra/vic-flip.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tegra.h"
+
+#include "host1x.h"
+#include "vic.h"
+
+/* clear output image to red */
+static int clear(struct vic *vic, struct drm_tegra_channel *channel,
+ struct vic_image *output)
+{
+struct drm_tegra_pushbuf *pushbuf;
+struct drm_tegra_job *job;
+uint32_t *ptr;
+int err;
+
+err = drm_tegra_job_new(channel, );
+if (err < 0) {
+fprintf(stderr, "failed to create job: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_job_get_pushbuf(job, );
+if (err < 0) {
+fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_pushbuf_begin(pushbuf, 32, );
+if (err < 0) {
+fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err));
+return err;
+}
+
+err = vic->ops->clear(vic, output, 1023, 0, 0, 1023);
+if (err < 0) {
+fprintf(stderr, "failed to clear surface: %s\n", strerror(-err));
+return err;
+}
+
+err = vic->ops->execute(vic, pushbuf, , output, NULL, 0);
+if (err < 0) {
+fprintf(stderr, "failed to execute operation: %s\n", strerror(-err));
+return err;
+}
+
+err = drm_tegra_pushbuf_sync_cond(pushbuf, , vic->syncpt,
+  DRM_TEGRA_SYNC_COND_OP_DONE);
+if (err < 0) {
+fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err));
+return err;
+}
+
+err = drm_tegra_pushbuf_end(pushbuf, ptr);
+if (err < 0) {
+fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err));
+return err;
+}
+
+err = drm_tegra_job_submit(job, NULL);
+if (err < 0) {
+fprintf(stderr, "failed to submit job: %s\n", strerror(-err));
+return err;
+}
+
+err = drm_tegra_job_wait(job, 10);
+if (err < 0) {
+fprintf(stderr, "failed to wait for job: %s\n", strerror(-err));
+return err;
+}
+
+drm_tegra_job_free(job);
+
+return 0;
+}
+
+/* fill bottom half of image to blue */
+static int fill(struct vic *vic, struct drm_tegra_channel *channel,
+struct vic_image *output)
+{
+struct drm_tegra_pushbuf *pushbuf;
+struct drm_tegra_job *job;
+uint32_t *ptr;
+int err;
+
+err = drm_tegra_job_new(channel, );
+if (err < 0) {
+fprintf(stderr, "failed to create job: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_job_get_pushbuf(job, );
+if (err < 0) {
+fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_pushbuf_begin(pushbuf, 32, );
+if 

[PATCH libdrm 19/25] tests: tegra: Add VIC 3.0 support

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

The Video Image Composer (VIC) 3.0 can be found on NVIDIA Tegra124 SoCs.

Signed-off-by: Thierry Reding 
---
 tegra/private.h |   6 +
 tests/tegra/meson.build |   2 +
 tests/tegra/vic.c   |   8 +-
 tests/tegra/vic30.c | 509 
 tests/tegra/vic30.h | 439 ++
 5 files changed, 962 insertions(+), 2 deletions(-)
 create mode 100644 tests/tegra/vic30.c
 create mode 100644 tests/tegra/vic30.h

diff --git a/tegra/private.h b/tegra/private.h
index f134f3ea2cea..821eb0e48fd0 100644
--- a/tegra/private.h
+++ b/tegra/private.h
@@ -26,6 +26,7 @@
 #define __DRM_TEGRA_PRIVATE_H__ 1
 
 #include 
+#include 
 #include 
 
 #include 
@@ -34,6 +35,11 @@
 #include "tegra_drm.h"
 #include "tegra.h"
 
+#define container_of(ptr, type, member) ({  \
+const typeof(((type *)0)->member) *__mptr = (ptr);  \
+(type *)((char *)__mptr - offsetof(type, member));  \
+})
+
 enum host1x_class {
 HOST1X_CLASS_HOST1X = 0x01,
 HOST1X_CLASS_GR2D = 0x51,
diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index 55c1c72808e3..934b728a48d9 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -34,6 +34,8 @@ libdrm_test_tegra = static_library(
 'drm-test-tegra.h',
 'vic.c',
 'vic.h',
+'vic30.c',
+'vic30.h',
   ), config_file ],
   include_directories : [inc_root, inc_drm, inc_tegra],
   link_with : libdrm,
diff --git a/tests/tegra/vic.c b/tests/tegra/vic.c
index 02ba4a25ae47..6001a0cdb9d2 100644
--- a/tests/tegra/vic.c
+++ b/tests/tegra/vic.c
@@ -130,6 +130,10 @@ void vic_image_dump(struct vic_image *image, FILE *fp)
 drm_tegra_bo_unmap(image->bo);
 }
 
+/* from vic30.c */
+int vic30_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
+  struct vic **vicp);
+
 int vic_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
 struct vic **vicp)
 {
@@ -138,8 +142,8 @@ int vic_new(struct drm_tegra *drm, struct drm_tegra_channel 
*channel,
 version = drm_tegra_channel_get_version(channel);
 
 switch (version) {
-default:
-break;
+case 0x40:
+return vic30_new(drm, channel, vicp);
 }
 
 return -ENOTSUP;
diff --git a/tests/tegra/vic30.c b/tests/tegra/vic30.c
new file mode 100644
index ..5db83e08e003
--- /dev/null
+++ b/tests/tegra/vic30.c
@@ -0,0 +1,509 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+
+#include "private.h"
+#include "tegra.h"
+#include "vic.h"
+#include "vic30.h"
+
+struct vic30 {
+struct vic base;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} config;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} filter;
+
+struct {
+struct drm_tegra_mapping *map;
+struct drm_tegra_bo *bo;
+} hist;
+};
+
+static int vic30_clear(struct vic *v, struct vic_image *output,
+   unsigned int alpha, unsigned int red,
+   unsigned int green, unsigned int blue)
+{
+struct vic30 *vic = container_of(v, struct vic30, base);
+ConfigStruct *c;
+int err;
+
+err = drm_tegra_bo_map(vic->config.bo, (void **));
+if (err < 0) {
+fprintf(stderr, "failed to map configuration structure: %s\n",
+strerror(-err));
+return err;
+}
+
+memset(c, 0, sizeof(*c));
+
+c->surfaceList0Struct.TargetRectLeft = 0;
+c->surfaceList0Struct.TargetRectTop = 0;
+c->surfaceList0Struct.TargetRectRight = output->width - 1;
+c->surfaceList0Struct.TargetRectBottom = output->height - 1;
+
+c->blending0Struct.PixelFormat = output->format;
+c->blending0Struct.BackgroundAlpha = alpha;
+c->blending0Struct.BackgroundR = red;
+c->blending0Struct.BackgroundG 

[PATCH libdrm 16/25] tests: tegra: Add syncpt-wait test

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

This is a very simple sanity test to check whether or not a syncpt can
be incremented by a host1x client. This uses gr2d on Tegra20 through
Tegra114 and VIC on Tegra124 and later.

Signed-off-by: Thierry Reding 
---
 tests/tegra/meson.build   |   9 +++
 tests/tegra/syncpt-wait.c | 151 ++
 2 files changed, 160 insertions(+)
 create mode 100644 tests/tegra/syncpt-wait.c

diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index b4aea33f4298..8b1b8bf58dd1 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -54,3 +54,12 @@ gr2d_fill = executable(
   link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra],
   install : with_install_tests,
 )
+
+syncpt_wait = executable(
+  'tegra-syncpt-wait',
+  files('syncpt-wait.c'),
+  include_directories : [inc_root, inc_drm, inc_tegra],
+  c_args : warn_c_args,
+  link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra],
+  install : with_install_tests,
+)
diff --git a/tests/tegra/syncpt-wait.c b/tests/tegra/syncpt-wait.c
new file mode 100644
index ..f18117425f6d
--- /dev/null
+++ b/tests/tegra/syncpt-wait.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tegra.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+static int channel_open(struct drm_tegra *drm,
+struct drm_tegra_channel **channel)
+{
+static const struct {
+enum drm_tegra_class class;
+const char *name;
+} classes[] = {
+{ DRM_TEGRA_VIC,  "VIC"  },
+{ DRM_TEGRA_GR2D, "GR2D" },
+};
+unsigned int i;
+int err;
+
+for (i = 0; i < ARRAY_SIZE(classes); i++) {
+err = drm_tegra_channel_open(drm, classes[i].class, channel);
+if (err < 0) {
+fprintf(stderr, "failed to open channel to %s: %s\n",
+classes[i].name, strerror(-err));
+continue;
+}
+
+break;
+}
+
+return err;
+}
+
+int main(int argc, char *argv[])
+{
+const char *device = "/dev/dri/renderD128";
+struct drm_tegra_syncpoint *syncpt;
+struct drm_tegra_channel *channel;
+struct drm_tegra_pushbuf *pushbuf;
+struct drm_tegra_job *job;
+struct drm_tegra *drm;
+uint32_t *ptr;
+int fd, err;
+
+if (argc > 1)
+device = argv[1];
+
+fd = open(device, O_RDWR);
+if (fd < 0) {
+fprintf(stderr, "open() failed: %s\n", strerror(errno));
+return 1;
+}
+
+err = drm_tegra_new(fd, );
+if (err < 0) {
+fprintf(stderr, "failed to open Tegra device: %s\n", strerror(-err));
+close(fd);
+return 1;
+}
+
+err = drm_tegra_syncpoint_new(drm, );
+if (err < 0) {
+fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err));
+drm_tegra_close(drm);
+close(fd);
+return 1;
+}
+
+err = channel_open(drm, );
+if (err < 0) {
+fprintf(stderr, "failed to open channel: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_job_new(channel, );
+if (err < 0) {
+fprintf(stderr, "failed to create job: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_job_get_pushbuf(job, );
+if (err < 0) {
+fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_pushbuf_begin(pushbuf, 4, );
+if (err < 0) {
+fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_pushbuf_sync_cond(pushbuf, , syncpt,
+  DRM_TEGRA_SYNC_COND_IMMEDIATE);
+if (err < 0) {
+fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err));
+return 1;
+}
+
+

[PATCH libdrm 18/25] tests: tegra: Add VIC support

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

Implement a small abstraction interface to allow different versions of
VIC to be used transparently. An implementation will be chosen based on
the VIC version number reported by the DRM_TEGRA_IOCTL_OPEN_CHANNEL
IOCTL.

Signed-off-by: Thierry Reding 
---
 tests/tegra/host1x.h|  34 
 tests/tegra/meson.build |   2 +
 tests/tegra/vic.c   | 152 +
 tests/tegra/vic.h   | 181 
 4 files changed, 369 insertions(+)
 create mode 100644 tests/tegra/host1x.h
 create mode 100644 tests/tegra/vic.c
 create mode 100644 tests/tegra/vic.h

diff --git a/tests/tegra/host1x.h b/tests/tegra/host1x.h
new file mode 100644
index ..902b0c12ee6d
--- /dev/null
+++ b/tests/tegra/host1x.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef HOST1X_H
+#define HOST1X_H
+
+#define HOST1X_OPCODE_SETCL(offset, classid, mask) \
+((0x0 << 28) | (((offset) & 0xfff) << 16) | (((classid) & 0x3ff) << 6) | 
((mask) & 0x3f))
+
+#define HOST1X_OPCODE_INCR(offset, count) \
+((0x1 << 28) | (((offset) & 0xfff) << 16) | ((count) & 0x))
+
+#define HOST1X_CLASS_VIC 0x5d
+
+#endif
diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index 4b05569e0971..55c1c72808e3 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -32,6 +32,8 @@ libdrm_test_tegra = static_library(
   [files(
 'drm-test-tegra.c',
 'drm-test-tegra.h',
+'vic.c',
+'vic.h',
   ), config_file ],
   include_directories : [inc_root, inc_drm, inc_tegra],
   link_with : libdrm,
diff --git a/tests/tegra/vic.c b/tests/tegra/vic.c
new file mode 100644
index ..02ba4a25ae47
--- /dev/null
+++ b/tests/tegra/vic.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include  /* XXX remove */
+#include 
+
+#include "util_math.h"
+
+#include "tegra.h"
+#include "host1x.h"
+#include "vic.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+const struct vic_format_info *vic_format_get_info(unsigned int format)
+{
+static const struct vic_format_info formats[] = {
+{ .format = VIC_PIXEL_FORMAT_A8R8G8B8, .cpp = 4 },
+};
+unsigned int i;
+
+for (i = 0; i < ARRAY_SIZE(formats); i++) {
+if (formats[i].format == format)
+return [i];
+}
+
+return 0;
+}
+
+int vic_image_new(struct vic *vic, unsigned int width, unsigned int height,
+  unsigned int format, unsigned int kind, uint32_t flags,
+  struct vic_image **imagep)
+{
+const struct vic_format_info *info = vic_format_get_info(format);
+struct vic_image *image;
+int err;
+
+if (!info)
+return -EINVAL;
+
+image = calloc(1, sizeof(*image));
+if 

[PATCH libdrm 14/25] tests: tegra: Add helper library for tests

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

This library provides helpers for common functionality needed by test
programs.

Signed-off-by: Thierry Reding 
---
 tests/tegra/drm-test.c  | 248 
 tests/tegra/drm-test.h  |  72 
 tests/tegra/meson.build |   7 ++
 3 files changed, 327 insertions(+)
 create mode 100644 tests/tegra/drm-test.c
 create mode 100644 tests/tegra/drm-test.h

diff --git a/tests/tegra/drm-test.c b/tests/tegra/drm-test.c
new file mode 100644
index ..b1ded9cf5fac
--- /dev/null
+++ b/tests/tegra/drm-test.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright © 2014 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "xf86drm.h"
+#include "xf86drmMode.h"
+#include "drm_fourcc.h"
+
+#include "drm-test.h"
+
+static int drm_screen_probe_connector(struct drm_screen *screen,
+  drmModeConnectorPtr connector)
+{
+drmModeEncoderPtr encoder;
+drmModeCrtcPtr crtc;
+drmModeFBPtr fb;
+
+encoder = drmModeGetEncoder(screen->fd, connector->encoder_id);
+if (!encoder)
+return -ENODEV;
+
+crtc = drmModeGetCrtc(screen->fd, encoder->crtc_id);
+if (!crtc) {
+drmModeFreeEncoder(encoder);
+return -ENODEV;
+}
+
+screen->old_fb = crtc->buffer_id;
+
+fb = drmModeGetFB(screen->fd, crtc->buffer_id);
+if (!fb) {
+/* TODO: create new framebuffer */
+drmModeFreeEncoder(encoder);
+drmModeFreeCrtc(crtc);
+return -ENOSYS;
+}
+
+screen->connector = connector->connector_id;
+screen->old_fb = crtc->buffer_id;
+screen->crtc = encoder->crtc_id;
+/* TODO: check crtc->mode_valid */
+screen->mode = crtc->mode;
+
+screen->width = fb->width;
+screen->height = fb->height;
+screen->pitch = fb->pitch;
+screen->depth = fb->depth;
+screen->bpp = fb->bpp;
+
+drmModeFreeEncoder(encoder);
+drmModeFreeCrtc(crtc);
+drmModeFreeFB(fb);
+
+return 0;
+}
+
+int drm_screen_open(struct drm_screen **screenp, int fd)
+{
+drmModeConnectorPtr connector;
+struct drm_screen *screen;
+bool found = false;
+drmModeResPtr res;
+unsigned int i;
+int err;
+
+if (!screenp || fd < 0)
+return -EINVAL;
+
+screen = calloc(1, sizeof(*screen));
+if (!screen)
+return -ENOMEM;
+
+screen->format = DRM_FORMAT_XRGB;
+screen->fd = fd;
+
+res = drmModeGetResources(fd);
+if (!res) {
+free(screen);
+return -ENOMEM;
+}
+
+for (i = 0; i < (unsigned int)res->count_connectors; i++) {
+connector = drmModeGetConnector(fd, res->connectors[i]);
+if (!connector)
+continue;
+
+if (connector->connection != DRM_MODE_CONNECTED) {
+drmModeFreeConnector(connector);
+continue;
+}
+
+err = drm_screen_probe_connector(screen, connector);
+if (err < 0) {
+drmModeFreeConnector(connector);
+continue;
+}
+
+drmModeFreeConnector(connector);
+found = true;
+break;
+}
+
+drmModeFreeResources(res);
+
+if (!found) {
+free(screen);
+return -ENODEV;
+}
+
+*screenp = screen;
+
+return 0;
+}
+
+int drm_screen_close(struct drm_screen *screen)
+{
+int err;
+
+err = drmModeSetCrtc(screen->fd, screen->crtc, screen->old_fb, 0, 0,
+ >connector, 1, >mode);
+if (err < 0) {
+fprintf(stderr, "drmModeSetCrtc() failed: %m\n");
+return -errno;
+}
+
+free(screen);
+
+return 0;
+}
+
+int drm_framebuffer_new(struct drm_framebuffer **fbp,
+struct drm_screen *screen, uint32_t handle,
+unsigned int width, 

[PATCH libdrm 10/25] tegra: Include private.h in list of source files

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

This makes sure that the proper dependencies are created and that the
file is distributed.

Signed-off-by: Thierry Reding 
---
 tegra/meson.build | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tegra/meson.build b/tegra/meson.build
index edddf72bc0e7..9813d9baddac 100644
--- a/tegra/meson.build
+++ b/tegra/meson.build
@@ -20,7 +20,12 @@
 
 libdrm_tegra = library(
   'drm_tegra',
-  [files('tegra.c'), config_file],
+  [
+files(
+  'private.h', 'tegra.c'
+),
+config_file
+  ],
   include_directories : [inc_root, inc_drm],
   link_with : libdrm,
   dependencies : [dep_pthread_stubs, dep_atomic_ops],
-- 
2.32.0



[PATCH libdrm 15/25] tests: tegra: Add gr2d-fill test

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

This test uses the IOCTLs for job submission and fences to fill a sub-
region of the screen to a specific color using gr2d.

Signed-off-by: Thierry Reding 
---
 tests/tegra/.gitignore   |   1 +
 tests/tegra/drm-test-tegra.c | 147 +++
 tests/tegra/drm-test-tegra.h |  55 +
 tests/tegra/gr2d-fill.c  | 146 ++
 tests/tegra/meson.build  |  19 +
 5 files changed, 368 insertions(+)
 create mode 100644 tests/tegra/drm-test-tegra.c
 create mode 100644 tests/tegra/drm-test-tegra.h
 create mode 100644 tests/tegra/gr2d-fill.c

diff --git a/tests/tegra/.gitignore b/tests/tegra/.gitignore
index 56cfb62b785f..0db9e5401302 100644
--- a/tests/tegra/.gitignore
+++ b/tests/tegra/.gitignore
@@ -1 +1,2 @@
+tegra-gr2d-fill
 tegra-openclose
diff --git a/tests/tegra/drm-test-tegra.c b/tests/tegra/drm-test-tegra.c
new file mode 100644
index ..1a9fa8961de9
--- /dev/null
+++ b/tests/tegra/drm-test-tegra.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright © 2014 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include 
+#include 
+
+#include "drm-test-tegra.h"
+#include "tegra.h"
+
+int drm_tegra_gr2d_open(struct drm_tegra *drm, struct drm_tegra_gr2d **gr2dp)
+{
+struct drm_tegra_gr2d *gr2d;
+int err;
+
+gr2d = calloc(1, sizeof(*gr2d));
+if (!gr2d)
+return -ENOMEM;
+
+gr2d->drm = drm;
+
+err = drm_tegra_channel_open(drm, DRM_TEGRA_GR2D, >channel);
+if (err < 0) {
+free(gr2d);
+return err;
+}
+
+*gr2dp = gr2d;
+
+return 0;
+}
+
+int drm_tegra_gr2d_close(struct drm_tegra_gr2d *gr2d)
+{
+if (!gr2d)
+return -EINVAL;
+
+drm_tegra_channel_close(gr2d->channel);
+free(gr2d);
+
+return 0;
+}
+
+int drm_tegra_gr2d_fill(struct drm_tegra_gr2d *gr2d, struct drm_framebuffer 
*fb,
+unsigned int x, unsigned int y, unsigned int width,
+unsigned int height, uint32_t color)
+{
+struct drm_tegra_bo *fbo = fb->data;
+struct drm_tegra_pushbuf *pushbuf;
+struct drm_tegra_mapping *map;
+struct drm_tegra_job *job;
+uint32_t *ptr;
+int err;
+
+err = drm_tegra_job_new(gr2d->channel, );
+if (err < 0)
+return err;
+
+err = drm_tegra_channel_map(gr2d->channel, fbo, 0, );
+if (err < 0)
+return err;
+
+err = drm_tegra_job_get_pushbuf(job, );
+if (err < 0)
+return err;
+
+err = drm_tegra_pushbuf_begin(pushbuf, 32, );
+if (err < 0)
+return err;
+
+*ptr++ = HOST1X_OPCODE_SETCL(0, HOST1X_CLASS_GR2D, 0);
+
+*ptr++ = HOST1X_OPCODE_MASK(0x9, 0x9);
+*ptr++ = 0x003a;
+*ptr++ = 0x;
+
+*ptr++ = HOST1X_OPCODE_MASK(0x1e, 0x7);
+*ptr++ = 0x;
+*ptr++ = (2 << 16) | (1 << 6) | (1 << 2);
+*ptr++ = 0x00cc;
+
+*ptr++ = HOST1X_OPCODE_MASK(0x2b, 0x9);
+
+/* relocate destination buffer */
+err = drm_tegra_pushbuf_relocate(pushbuf, , map, 0, 0, 0);
+if (err < 0) {
+fprintf(stderr, "failed to relocate buffer object: %d\n", err);
+return err;
+}
+
+*ptr++ = fb->pitch;
+
+*ptr++ = HOST1X_OPCODE_NONINCR(0x35, 1);
+*ptr++ = color;
+
+*ptr++ = HOST1X_OPCODE_NONINCR(0x46, 1);
+*ptr++ = 0x;
+
+*ptr++ = HOST1X_OPCODE_MASK(0x38, 0x5);
+*ptr++ = height << 16 | width;
+*ptr++ = y << 16 | x;
+
+err = drm_tegra_pushbuf_end(pushbuf, ptr);
+if (err < 0) {
+fprintf(stderr, "failed to update push buffer: %d\n", -err);
+return err;
+}
+
+err = drm_tegra_job_submit(job, NULL);
+if (err < 0) {
+fprintf(stderr, "failed to submit job: %d\n", err);
+return err;
+}
+
+err = drm_tegra_job_wait(job, 0);
+if (err < 0) {
+fprintf(stderr, "failed to wait for fence: %d\n", err);

[PATCH libdrm 17/25] tests: tegra: Add syncpoint timeout test

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

This test can be used to purposefully trigger a job timeout.

Signed-off-by: Thierry Reding 
---
 tests/tegra/meson.build  |   9 ++
 tests/tegra/syncpt-timeout.c | 163 +++
 2 files changed, 172 insertions(+)
 create mode 100644 tests/tegra/syncpt-timeout.c

diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index 8b1b8bf58dd1..4b05569e0971 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -63,3 +63,12 @@ syncpt_wait = executable(
   link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra],
   install : with_install_tests,
 )
+
+syncpt_timeout = executable(
+  'tegra-syncpt-timeout',
+  files('syncpt-timeout.c'),
+  include_directories : [inc_root, inc_drm, inc_tegra],
+  c_args : warn_c_args,
+  link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra],
+  install : with_install_tests,
+)
diff --git a/tests/tegra/syncpt-timeout.c b/tests/tegra/syncpt-timeout.c
new file mode 100644
index ..fea3665cb126
--- /dev/null
+++ b/tests/tegra/syncpt-timeout.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright © 2018 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tegra.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+static int channel_open(struct drm_tegra *drm,
+struct drm_tegra_channel **channel)
+{
+static const struct {
+enum drm_tegra_class class;
+const char *name;
+} classes[] = {
+{ DRM_TEGRA_VIC,  "VIC"  },
+{ DRM_TEGRA_GR2D, "GR2D" },
+};
+unsigned int i;
+int err;
+
+for (i = 0; i < ARRAY_SIZE(classes); i++) {
+err = drm_tegra_channel_open(drm, classes[i].class, channel);
+if (err < 0) {
+fprintf(stderr, "failed to open channel to %s: %s\n",
+classes[i].name, strerror(-err));
+continue;
+}
+
+break;
+}
+
+return err;
+}
+
+int main(int argc, char *argv[])
+{
+const char *device = "/dev/dri/renderD128";
+struct drm_tegra_syncpoint *syncpt;
+struct drm_tegra_channel *channel;
+struct drm_tegra_pushbuf *pushbuf;
+struct drm_tegra_job *job;
+struct drm_tegra *drm;
+uint32_t *ptr;
+int fd, err;
+
+if (argc > 1)
+device = argv[1];
+
+fd = open(device, O_RDWR);
+if (fd < 0) {
+fprintf(stderr, "open() failed: %s\n", strerror(errno));
+return 1;
+}
+
+err = drm_tegra_new(fd, );
+if (err < 0) {
+fprintf(stderr, "failed to open Tegra device: %s\n", strerror(-err));
+close(fd);
+return 1;
+}
+
+err = drm_tegra_syncpoint_new(drm, );
+if (err < 0) {
+fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err));
+drm_tegra_close(drm);
+close(fd);
+return 1;
+}
+
+err = channel_open(drm, );
+if (err < 0) {
+fprintf(stderr, "failed to open channel: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_job_new(channel, );
+if (err < 0) {
+fprintf(stderr, "failed to create job: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_job_get_pushbuf(job, );
+if (err < 0) {
+fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
+return 1;
+}
+
+err = drm_tegra_pushbuf_begin(pushbuf, 8, );
+if (err < 0) {
+fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err));
+return 1;
+}
+
+/*
+ * Empty command streams will be rejected, so we use this as an easy way
+ * to add something to the command stream. But this could be any other,
+ * valid command stream.
+ */
+err = drm_tegra_pushbuf_sync_cond(pushbuf, , syncpt,
+  DRM_TEGRA_SYNC_COND_IMMEDIATE);
+if (err < 0) {
+ 

[PATCH libdrm 12/25] tegra: Add job and push buffer APIs

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

These new functions can be used to create a job on a given channel, add
commands to the job using its push buffer and submit the job.

Signed-off-by: Thierry Reding 
---
 tegra/job.c | 164 
 tegra/meson.build   |   2 +-
 tegra/private.h |  32 
 tegra/pushbuf.c | 136 +
 tegra/tegra-symbols.txt |   7 ++
 tegra/tegra.h   |  34 +
 6 files changed, 374 insertions(+), 1 deletion(-)
 create mode 100644 tegra/job.c
 create mode 100644 tegra/pushbuf.c

diff --git a/tegra/job.c b/tegra/job.c
new file mode 100644
index ..c8c94e131ef0
--- /dev/null
+++ b/tegra/job.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright © 2012, 2013 Thierry Reding
+ * Copyright © 2013 Erik Faye-Lund
+ * Copyright © 2014 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "private.h"
+
+struct drm_tegra_submit_cmd *
+drm_tegra_job_add_command(struct drm_tegra_job *job, uint32_t type,
+  uint32_t flags)
+{
+struct drm_tegra_submit_cmd *commands, *command;
+size_t size;
+
+size = (job->num_commands + 1) * sizeof(*commands);
+
+commands = realloc(job->commands, size);
+if (!commands)
+return NULL;
+
+command = [job->num_commands];
+memset(command, 0, sizeof(*command));
+command->type = type;
+command->flags = flags;
+
+job->commands = commands;
+job->num_commands++;
+
+return command;
+}
+
+drm_public int
+drm_tegra_job_new(struct drm_tegra_channel *channel,
+  struct drm_tegra_job **jobp)
+{
+struct drm_tegra_job *job;
+
+job = calloc(1, sizeof(*job));
+if (!job)
+return -ENOMEM;
+
+job->page_size = sysconf(_SC_PAGESIZE);
+job->channel = channel;
+
+*jobp = job;
+
+return 0;
+}
+
+drm_public int drm_tegra_job_free(struct drm_tegra_job *job)
+{
+if (!job)
+return -EINVAL;
+
+if (job->pushbuf)
+drm_tegra_pushbuf_free(job->pushbuf);
+
+if (job->commands)
+free(job->commands);
+
+if (job->buffers)
+free(job->buffers);
+
+free(job);
+
+return 0;
+}
+
+drm_public int
+drm_tegra_job_get_pushbuf(struct drm_tegra_job *job,
+  struct drm_tegra_pushbuf **pushbufp)
+{
+struct drm_tegra_pushbuf *pushbuf;
+
+if (!job->pushbuf) {
+pushbuf = calloc(1, sizeof(*pushbuf));
+if (!pushbuf)
+return -ENOMEM;
+
+pushbuf->job = job;
+
+pushbuf->start = calloc(1, job->page_size);
+if (!pushbuf->start) {
+free(pushbuf);
+return -ENOMEM;
+}
+
+pushbuf->end = pushbuf->start + job->page_size / 4;
+pushbuf->ptr = pushbuf->start;
+
+job->pushbuf = pushbuf;
+}
+
+*pushbufp = job->pushbuf;
+
+return 0;
+}
+
+drm_public int
+drm_tegra_job_submit(struct drm_tegra_job *job, struct drm_tegra_fence *fence)
+{
+struct drm_tegra_channel *channel = job->channel;
+struct drm_tegra *drm = channel->drm;
+struct drm_tegra_channel_submit args;
+int err;
+
+memset(, 0, sizeof(args));
+args.context = channel->context;
+args.num_bufs = job->num_buffers;
+args.num_cmds = job->num_commands;
+args.gather_data_words = job->pushbuf->ptr - job->pushbuf->start;
+args.syncpt.id = job->syncpt.id;
+args.syncpt.increments = job->syncpt.increments;
+
+args.bufs_ptr = (uintptr_t)job->buffers;
+args.cmds_ptr = (uintptr_t)job->commands;
+args.gather_data_ptr = (uintptr_t)job->pushbuf->start;
+
+err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_SUBMIT, );
+if (err < 0)
+return -errno;
+
+job->syncpt.fence = args.syncpt.value;
+
+if (fence) {
+

[PATCH libdrm 09/25] tegra: Update for new UABI

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

This new UABI is a more modern version that works better with both old
and recent chips.

Signed-off-by: Thierry Reding 
---
 include/drm/tegra_drm.h | 429 +---
 1 file changed, 404 insertions(+), 25 deletions(-)

diff --git a/include/drm/tegra_drm.h b/include/drm/tegra_drm.h
index 6c07919c04e9..94cfc306d50a 100644
--- a/include/drm/tegra_drm.h
+++ b/include/drm/tegra_drm.h
@@ -1,27 +1,8 @@
-/*
- * Copyright (c) 2012-2013, NVIDIA CORPORATION.  All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
+/* SPDX-License-Identifier: MIT */
+/* Copyright (c) 2012-2020 NVIDIA Corporation */
 
-#ifndef _TEGRA_DRM_H_
-#define _TEGRA_DRM_H_
+#ifndef _UAPI_TEGRA_DRM_H_
+#define _UAPI_TEGRA_DRM_H_
 
 #include "drm.h"
 
@@ -29,6 +10,8 @@
 extern "C" {
 #endif
 
+/* Tegra DRM legacy UAPI. Only enabled with STAGING */
+
 #define DRM_TEGRA_GEM_CREATE_TILED (1 << 0)
 #define DRM_TEGRA_GEM_CREATE_BOTTOM_UP (1 << 1)
 
@@ -649,8 +632,8 @@ struct drm_tegra_gem_get_flags {
 #define DRM_TEGRA_SYNCPT_READ  0x02
 #define DRM_TEGRA_SYNCPT_INCR  0x03
 #define DRM_TEGRA_SYNCPT_WAIT  0x04
-#define DRM_TEGRA_OPEN_CHANNEL 0x05
-#define DRM_TEGRA_CLOSE_CHANNEL0x06
+#define DRM_TEGRA_OPEN_CHANNEL 0x05
+#define DRM_TEGRA_CLOSE_CHANNEL0x06
 #define DRM_TEGRA_GET_SYNCPT   0x07
 #define DRM_TEGRA_SUBMIT   0x08
 #define DRM_TEGRA_GET_SYNCPT_BASE  0x09
@@ -674,6 +657,402 @@ struct drm_tegra_gem_get_flags {
 #define DRM_IOCTL_TEGRA_GEM_SET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + 
DRM_TEGRA_GEM_SET_FLAGS, struct drm_tegra_gem_set_flags)
 #define DRM_IOCTL_TEGRA_GEM_GET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + 
DRM_TEGRA_GEM_GET_FLAGS, struct drm_tegra_gem_get_flags)
 
+/* New Tegra DRM UAPI */
+
+/*
+ * Reported by the driver in the `capabilities` field.
+ *
+ * DRM_TEGRA_CHANNEL_CAP_CACHE_COHERENT: If set, the engine is cache coherent
+ * with regard to the system memory.
+ */
+#define DRM_TEGRA_CHANNEL_CAP_CACHE_COHERENT (1 << 0)
+
+struct drm_tegra_channel_open {
+   /**
+* @host1x_class: [in]
+*
+* Host1x class of the engine that will be programmed using this
+* channel.
+*/
+   __u32 host1x_class;
+
+   /**
+* @flags: [in]
+*
+* Flags.
+*/
+   __u32 flags;
+
+   /**
+* @context: [out]
+*
+* Opaque identifier corresponding to the opened channel.
+*/
+   __u32 context;
+
+   /**
+* @version: [out]
+*
+* Version of the engine hardware. This can be used by userspace
+* to determine how the engine needs to be programmed.
+*/
+   __u32 version;
+
+   /**
+* @capabilities: [out]
+*
+* Flags describing the hardware capabilities.
+*/
+   __u32 capabilities;
+   __u32 padding;
+};
+
+struct drm_tegra_channel_close {
+   /**
+* @context: [in]
+*
+* Identifier of the channel to close.
+*/
+   __u32 context;
+   __u32 padding;
+};
+
+/*
+ * Mapping flags that can be used to influence how the mapping is created.
+ *
+ * DRM_TEGRA_CHANNEL_MAP_READ: create mapping that allows HW read access
+ * DRM_TEGRA_CHANNEL_MAP_WRITE: create mapping that allows HW write access
+ */
+#define DRM_TEGRA_CHANNEL_MAP_READ  (1 << 0)
+#define DRM_TEGRA_CHANNEL_MAP_WRITE (1 << 1)
+#define DRM_TEGRA_CHANNEL_MAP_READ_WRITE (DRM_TEGRA_CHANNEL_MAP_READ | \
+ DRM_TEGRA_CHANNEL_MAP_WRITE)
+
+struct drm_tegra_channel_map {
+   /**
+* @context: [in]
+*
+* Identifier of the channel to which make memory available for.
+*/
+   __u32 context;
+
+   /**
+* @handle: [in]
+*
+* GEM handle of the memory to map.
+*/
+   __u32 

[PATCH libdrm 05/25] tegra: Add flink helpers

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

Add helpers to export and import buffer objects via flink names.

Signed-off-by: Thierry Reding 
---
Changes in v3:
- add drm_public annotations
---
 tegra/tegra-symbols.txt |  2 ++
 tegra/tegra.c   | 50 +
 tegra/tegra.h   |  3 +++
 3 files changed, 55 insertions(+)

diff --git a/tegra/tegra-symbols.txt b/tegra/tegra-symbols.txt
index 9422696c1416..630e075fa5d7 100644
--- a/tegra/tegra-symbols.txt
+++ b/tegra/tegra-symbols.txt
@@ -1,6 +1,8 @@
 drm_tegra_bo_get_handle
+drm_tegra_bo_get_name
 drm_tegra_bo_map
 drm_tegra_bo_new
+drm_tegra_bo_open
 drm_tegra_bo_ref
 drm_tegra_bo_unmap
 drm_tegra_bo_unref
diff --git a/tegra/tegra.c b/tegra/tegra.c
index 5225ad052fb3..5eb8518104ef 100644
--- a/tegra/tegra.c
+++ b/tegra/tegra.c
@@ -244,3 +244,53 @@ drm_public int drm_tegra_bo_unmap(struct drm_tegra_bo *bo)
 
 return 0;
 }
+
+drm_public int drm_tegra_bo_get_name(struct drm_tegra_bo *bo, uint32_t *name)
+{
+struct drm_tegra *drm = bo->drm;
+struct drm_gem_flink args;
+int err;
+
+memset(, 0, sizeof(args));
+args.handle = bo->handle;
+
+err = drmIoctl(drm->fd, DRM_IOCTL_GEM_FLINK, );
+if (err < 0)
+return err;
+
+if (name)
+*name = args.name;
+
+return 0;
+}
+
+drm_public int
+drm_tegra_bo_open(struct drm_tegra *drm, uint32_t name, uint32_t flags,
+  struct drm_tegra_bo **bop)
+{
+struct drm_gem_open args;
+struct drm_tegra_bo *bo;
+int err;
+
+bo = drm_tegra_bo_alloc(drm, 0, flags, 0);
+if (!bo)
+return -ENOMEM;
+
+memset(, 0, sizeof(args));
+args.name = name;
+
+err = drmIoctl(drm->fd, DRM_IOCTL_GEM_OPEN, );
+if (err < 0)
+goto free;
+
+bo->handle = args.handle;
+bo->size = args.size;
+
+*bop = bo;
+
+return 0;
+
+free:
+free(bo);
+return err;
+}
diff --git a/tegra/tegra.h b/tegra/tegra.h
index c6b4f984de45..333690f23118 100644
--- a/tegra/tegra.h
+++ b/tegra/tegra.h
@@ -44,5 +44,8 @@ int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t 
*handle);
 int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr);
 int drm_tegra_bo_unmap(struct drm_tegra_bo *bo);
 
+int drm_tegra_bo_get_name(struct drm_tegra_bo *bo, uint32_t *name);
+int drm_tegra_bo_open(struct drm_tegra *drm, uint32_t name, uint32_t flags,
+  struct drm_tegra_bo **bop);
 
 #endif /* __DRM_TEGRA_H__ */
-- 
2.32.0



[PATCH libdrm 08/25] tegra: Install tegra-openclose test

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

Allow this simple test to be installed so that it can easily be run on a
target device.

Signed-off-by: Thierry Reding 
---
 tests/tegra/.gitignore  | 2 +-
 tests/tegra/meson.build | 7 +--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/tests/tegra/.gitignore b/tests/tegra/.gitignore
index 5c5216c5c5e6..56cfb62b785f 100644
--- a/tests/tegra/.gitignore
+++ b/tests/tegra/.gitignore
@@ -1 +1 @@
-openclose
+tegra-openclose
diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
index 4f8c54f41553..fbf4e6d8d4a3 100644
--- a/tests/tegra/meson.build
+++ b/tests/tegra/meson.build
@@ -18,10 +18,13 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
+inc_tegra = include_directories('../../tegra')
+
 openclose = executable(
-  'openclose',
+  'tegra-openclose',
   files('openclose.c'),
-  include_directories : [inc_root, inc_drm, 
include_directories('../../tegra')],
+  include_directories : [inc_root, inc_drm, inc_tegra],
   c_args : libdrm_c_args,
   link_with : [libdrm, libdrm_tegra],
+  install : with_install_tests,
 )
-- 
2.32.0



[PATCH libdrm 06/25] tegra: Add PRIME support helpers

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

These helpers facilitate exporting and importing buffer objects to and
from PRIME file descriptors.

Signed-off-by: Thierry Reding 
---
Changes in v3:
- add drm_public annotations
---
 tegra/tegra-symbols.txt |  2 ++
 tegra/tegra.c   | 61 +
 tegra/tegra.h   |  4 +++
 3 files changed, 67 insertions(+)

diff --git a/tegra/tegra-symbols.txt b/tegra/tegra-symbols.txt
index 630e075fa5d7..f8811bcd26f4 100644
--- a/tegra/tegra-symbols.txt
+++ b/tegra/tegra-symbols.txt
@@ -1,5 +1,7 @@
+drm_tegra_bo_export
 drm_tegra_bo_get_handle
 drm_tegra_bo_get_name
+drm_tegra_bo_import
 drm_tegra_bo_map
 drm_tegra_bo_new
 drm_tegra_bo_open
diff --git a/tegra/tegra.c b/tegra/tegra.c
index 5eb8518104ef..240600c3c496 100644
--- a/tegra/tegra.c
+++ b/tegra/tegra.c
@@ -294,3 +294,64 @@ free:
 free(bo);
 return err;
 }
+
+drm_public int drm_tegra_bo_export(struct drm_tegra_bo *bo, uint32_t flags)
+{
+int fd, err;
+
+flags |= DRM_CLOEXEC;
+
+err = drmPrimeHandleToFD(bo->drm->fd, bo->handle, flags, );
+if (err < 0)
+return err;
+
+return fd;
+}
+
+static ssize_t fd_get_size(int fd)
+{
+ssize_t size, offset;
+int err;
+
+offset = lseek(fd, 0, SEEK_CUR);
+if (offset < 0)
+return -errno;
+
+size = lseek(fd, 0, SEEK_END);
+if (size < 0)
+return -errno;
+
+err = lseek(fd, offset, SEEK_SET);
+if (err < 0)
+return -errno;
+
+return size;
+}
+
+drm_public int
+drm_tegra_bo_import(struct drm_tegra *drm, int fd, struct drm_tegra_bo **bop)
+{
+struct drm_tegra_bo *bo;
+ssize_t size;
+int err;
+
+size = fd_get_size(fd);
+if (size < 0)
+return size;
+
+bo = drm_tegra_bo_alloc(drm, 0, 0, size);
+if (!bo)
+return -ENOMEM;
+
+err = drmPrimeFDToHandle(drm->fd, fd, >handle);
+if (err < 0)
+goto free;
+
+*bop = bo;
+
+return 0;
+
+free:
+free(bo);
+return err;
+}
diff --git a/tegra/tegra.h b/tegra/tegra.h
index 333690f23118..aaaf455fbc8e 100644
--- a/tegra/tegra.h
+++ b/tegra/tegra.h
@@ -48,4 +48,8 @@ int drm_tegra_bo_get_name(struct drm_tegra_bo *bo, uint32_t 
*name);
 int drm_tegra_bo_open(struct drm_tegra *drm, uint32_t name, uint32_t flags,
   struct drm_tegra_bo **bop);
 
+int drm_tegra_bo_export(struct drm_tegra_bo *bo, uint32_t flags);
+int drm_tegra_bo_import(struct drm_tegra *drm, int fd,
+struct drm_tegra_bo **bop);
+
 #endif /* __DRM_TEGRA_H__ */
-- 
2.32.0



[PATCH libdrm 07/25] tegra: Make API more consistent

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

Most functions in libdrm_tegra take as first parameter the object that
they operate on. Make the device and buffer object creation functions
follow the same scheme.

Signed-off-by: Thierry Reding 
---
 tegra/tegra.c   | 13 +++--
 tegra/tegra.h   | 10 +-
 tests/tegra/openclose.c |  2 +-
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/tegra/tegra.c b/tegra/tegra.c
index 240600c3c496..0020e9301bf3 100644
--- a/tegra/tegra.c
+++ b/tegra/tegra.c
@@ -70,7 +70,7 @@ static int drm_tegra_wrap(struct drm_tegra **drmp, int fd, 
bool close)
 return 0;
 }
 
-drm_public int drm_tegra_new(struct drm_tegra **drmp, int fd)
+drm_public int drm_tegra_new(int fd, struct drm_tegra **drmp)
 {
 bool supported = false;
 drmVersionPtr version;
@@ -122,8 +122,8 @@ static struct drm_tegra_bo *drm_tegra_bo_alloc(struct 
drm_tegra *drm,
 }
 
 drm_public int
-drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
- uint32_t flags, uint32_t size)
+drm_tegra_bo_new(struct drm_tegra *drm, uint32_t flags, uint32_t size,
+ struct drm_tegra_bo **bop)
 {
 struct drm_tegra_gem_create args;
 struct drm_tegra_bo *bo;
@@ -156,8 +156,8 @@ drm_tegra_bo_new(struct drm_tegra_bo **bop, struct 
drm_tegra *drm,
 }
 
 drm_public int
-drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm,
-  uint32_t handle, uint32_t flags, uint32_t size)
+drm_tegra_bo_wrap(struct drm_tegra *drm, uint32_t handle, uint32_t flags,
+  uint32_t size, struct drm_tegra_bo **bop)
 {
 struct drm_tegra_bo *bo;
 
@@ -187,7 +187,8 @@ drm_public void drm_tegra_bo_unref(struct drm_tegra_bo *bo)
 drm_tegra_bo_free(bo);
 }
 
-drm_public int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t 
*handle)
+drm_public int
+drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle)
 {
 if (!bo || !handle)
 return -EINVAL;
diff --git a/tegra/tegra.h b/tegra/tegra.h
index aaaf455fbc8e..2bcd596e2d61 100644
--- a/tegra/tegra.h
+++ b/tegra/tegra.h
@@ -31,13 +31,13 @@
 struct drm_tegra_bo;
 struct drm_tegra;
 
-int drm_tegra_new(struct drm_tegra **drmp, int fd);
+int drm_tegra_new(int fd, struct drm_tegra **drmp);
 void drm_tegra_close(struct drm_tegra *drm);
 
-int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
- uint32_t flags, uint32_t size);
-int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm,
-  uint32_t handle, uint32_t flags, uint32_t size);
+int drm_tegra_bo_new(struct drm_tegra *drm, uint32_t flags, uint32_t size,
+ struct drm_tegra_bo **bop);
+int drm_tegra_bo_wrap(struct drm_tegra *drm, uint32_t handle, uint32_t flags,
+  uint32_t size, struct drm_tegra_bo **bop);
 struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo);
 void drm_tegra_bo_unref(struct drm_tegra_bo *bo);
 int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle);
diff --git a/tests/tegra/openclose.c b/tests/tegra/openclose.c
index 104e83806f3a..61dbc2ba4f5f 100644
--- a/tests/tegra/openclose.c
+++ b/tests/tegra/openclose.c
@@ -56,7 +56,7 @@ int main(int argc, char *argv[])
 drmFreeVersion(version);
 }
 
-err = drm_tegra_new(, fd);
+err = drm_tegra_new(fd, );
 if (err < 0)
 return 1;
 
-- 
2.32.0



[PATCH libdrm 03/25] tegra: Extract common buffer object allocation code

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

All of the buffer object allocation functions use the same boilerplate
code. Move that code into a separate function that can be reused.

Signed-off-by: Thierry Reding 
---
 tegra/tegra.c | 35 ++-
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/tegra/tegra.c b/tegra/tegra.c
index 94840ad42795..bf8e5c9213ca 100644
--- a/tegra/tegra.c
+++ b/tegra/tegra.c
@@ -101,6 +101,26 @@ drm_public void drm_tegra_close(struct drm_tegra *drm)
 free(drm);
 }
 
+static struct drm_tegra_bo *drm_tegra_bo_alloc(struct drm_tegra *drm,
+   uint32_t handle,
+   uint32_t flags,
+   uint32_t size)
+{
+struct drm_tegra_bo *bo;
+
+bo = calloc(1, sizeof(*bo));
+if (!bo)
+return NULL;
+
+atomic_set(>ref, 1);
+bo->handle = handle;
+bo->flags = flags;
+bo->size = size;
+bo->drm = drm;
+
+return bo;
+}
+
 drm_public int
 drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
  uint32_t flags, uint32_t size)
@@ -112,15 +132,10 @@ drm_tegra_bo_new(struct drm_tegra_bo **bop, struct 
drm_tegra *drm,
 if (!drm || size == 0 || !bop)
 return -EINVAL;
 
-bo = calloc(1, sizeof(*bo));
+bo = drm_tegra_bo_alloc(drm, 0, flags, size);
 if (!bo)
 return -ENOMEM;
 
-atomic_set(>ref, 1);
-bo->flags = flags;
-bo->size = size;
-bo->drm = drm;
-
 memset(, 0, sizeof(args));
 args.flags = flags;
 args.size = size;
@@ -149,16 +164,10 @@ drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct 
drm_tegra *drm,
 if (!drm || !bop)
 return -EINVAL;
 
-bo = calloc(1, sizeof(*bo));
+bo = drm_tegra_bo_alloc(drm, handle, flags, size);
 if (!bo)
 return -ENOMEM;
 
-atomic_set(>ref, 1);
-bo->handle = handle;
-bo->flags = flags;
-bo->size = size;
-bo->drm = drm;
-
 *bop = bo;
 
 return 0;
-- 
2.32.0



[PATCH libdrm 02/25] tegra: Remove unused IOCTL implementations

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

The DRM_TEGRA_GEM_{GET,SET}_FLAGS and DRM_TEGRA_GEM_{GET,SET}_TILING
IOCTLs were badly designed and have since been obsoleted by framebuffer
modifiers. Remove these implementations to make it clear their usage is
discouraged.

Signed-off-by: Thierry Reding 
---
 tegra/tegra-symbols.txt |  4 --
 tegra/tegra.c   | 95 -
 tegra/tegra.h   | 12 --
 3 files changed, 111 deletions(-)

diff --git a/tegra/tegra-symbols.txt b/tegra/tegra-symbols.txt
index 5e3e955f2901..9422696c1416 100644
--- a/tegra/tegra-symbols.txt
+++ b/tegra/tegra-symbols.txt
@@ -1,11 +1,7 @@
-drm_tegra_bo_get_flags
 drm_tegra_bo_get_handle
-drm_tegra_bo_get_tiling
 drm_tegra_bo_map
 drm_tegra_bo_new
 drm_tegra_bo_ref
-drm_tegra_bo_set_flags
-drm_tegra_bo_set_tiling
 drm_tegra_bo_unmap
 drm_tegra_bo_unref
 drm_tegra_bo_wrap
diff --git a/tegra/tegra.c b/tegra/tegra.c
index 3caf0bc4e65e..94840ad42795 100644
--- a/tegra/tegra.c
+++ b/tegra/tegra.c
@@ -235,98 +235,3 @@ drm_public int drm_tegra_bo_unmap(struct drm_tegra_bo *bo)
 
 return 0;
 }
-
-drm_public int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags)
-{
-struct drm_tegra_gem_get_flags args;
-struct drm_tegra *drm = bo->drm;
-int err;
-
-if (!bo)
-return -EINVAL;
-
-memset(, 0, sizeof(args));
-args.handle = bo->handle;
-
-err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_GET_FLAGS, ,
-  sizeof(args));
-if (err < 0)
-return -errno;
-
-if (flags)
-*flags = args.flags;
-
-return 0;
-}
-
-drm_public int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags)
-{
-struct drm_tegra_gem_get_flags args;
-struct drm_tegra *drm = bo->drm;
-int err;
-
-if (!bo)
-return -EINVAL;
-
-memset(, 0, sizeof(args));
-args.handle = bo->handle;
-args.flags = flags;
-
-err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_SET_FLAGS, ,
-  sizeof(args));
-if (err < 0)
-return -errno;
-
-return 0;
-}
-
-drm_public int
-drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo,
-struct drm_tegra_bo_tiling *tiling)
-{
-struct drm_tegra_gem_get_tiling args;
-struct drm_tegra *drm = bo->drm;
-int err;
-
-if (!bo)
-return -EINVAL;
-
-memset(, 0, sizeof(args));
-args.handle = bo->handle;
-
-err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_GET_TILING, ,
-  sizeof(args));
-if (err < 0)
-return -errno;
-
-if (tiling) {
-tiling->mode = args.mode;
-tiling->value = args.value;
-}
-
-return 0;
-}
-
-drm_public int
-drm_tegra_bo_set_tiling(struct drm_tegra_bo *bo,
-const struct drm_tegra_bo_tiling *tiling)
-{
-struct drm_tegra_gem_set_tiling args;
-struct drm_tegra *drm = bo->drm;
-int err;
-
-if (!bo)
-return -EINVAL;
-
-memset(, 0, sizeof(args));
-args.handle = bo->handle;
-args.mode = tiling->mode;
-args.value = tiling->value;
-
-err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_SET_TILING, ,
-  sizeof(args));
-if (err < 0)
-return -errno;
-
-return 0;
-}
diff --git a/tegra/tegra.h b/tegra/tegra.h
index 62205a5174b4..c6b4f984de45 100644
--- a/tegra/tegra.h
+++ b/tegra/tegra.h
@@ -44,17 +44,5 @@ int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, 
uint32_t *handle);
 int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr);
 int drm_tegra_bo_unmap(struct drm_tegra_bo *bo);
 
-int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags);
-int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags);
-
-struct drm_tegra_bo_tiling {
-uint32_t mode;
-uint32_t value;
-};
-
-int drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo,
-struct drm_tegra_bo_tiling *tiling);
-int drm_tegra_bo_set_tiling(struct drm_tegra_bo *bo,
-const struct drm_tegra_bo_tiling *tiling);
 
 #endif /* __DRM_TEGRA_H__ */
-- 
2.32.0



[PATCH libdrm 04/25] tegra: Fix mmap() of GEM buffer objects

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

Store 64-bit offset values and use libdrm's built-in drm_mmap() function
instead of mmap() to ensure the full 64-bit offset is used.

Signed-off-by: Thierry Reding 
---
 tegra/private.h | 2 +-
 tegra/tegra.c   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tegra/private.h b/tegra/private.h
index 215dd3309bce..d0f2944bfb3a 100644
--- a/tegra/private.h
+++ b/tegra/private.h
@@ -41,7 +41,7 @@ struct drm_tegra {
 struct drm_tegra_bo {
 struct drm_tegra *drm;
 uint32_t handle;
-uint32_t offset;
+uint64_t offset;
 uint32_t flags;
 uint32_t size;
 atomic_t ref;
diff --git a/tegra/tegra.c b/tegra/tegra.c
index bf8e5c9213ca..5225ad052fb3 100644
--- a/tegra/tegra.c
+++ b/tegra/tegra.c
@@ -215,8 +215,8 @@ drm_public int drm_tegra_bo_map(struct drm_tegra_bo *bo, 
void **ptr)
 
 bo->offset = args.offset;
 
-bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
-   drm->fd, bo->offset);
+bo->map = drm_mmap(NULL, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
+   drm->fd, bo->offset);
 if (bo->map == MAP_FAILED) {
 bo->map = NULL;
 return -errno;
-- 
2.32.0



[PATCH libdrm 01/25] tegra: Indent according to .editorconfig

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

Reindent the sources according to the settings found in the newly added
.editorconfig.

Signed-off-by: Thierry Reding 
---
 tegra/private.h |  18 +-
 tegra/tegra.c   | 354 
 tegra/tegra.h   |  12 +-
 tests/tegra/openclose.c |  52 +++---
 4 files changed, 220 insertions(+), 216 deletions(-)

diff --git a/tegra/private.h b/tegra/private.h
index bb6c1a516530..215dd3309bce 100644
--- a/tegra/private.h
+++ b/tegra/private.h
@@ -34,18 +34,18 @@
 #include "tegra.h"
 
 struct drm_tegra {
-   bool close;
-   int fd;
+bool close;
+int fd;
 };
 
 struct drm_tegra_bo {
-   struct drm_tegra *drm;
-   uint32_t handle;
-   uint32_t offset;
-   uint32_t flags;
-   uint32_t size;
-   atomic_t ref;
-   void *map;
+struct drm_tegra *drm;
+uint32_t handle;
+uint32_t offset;
+uint32_t flags;
+uint32_t size;
+atomic_t ref;
+void *map;
 };
 
 #endif /* __DRM_TEGRA_PRIVATE_H__ */
diff --git a/tegra/tegra.c b/tegra/tegra.c
index cf00a3cac6d8..3caf0bc4e65e 100644
--- a/tegra/tegra.c
+++ b/tegra/tegra.c
@@ -37,292 +37,296 @@
 
 static void drm_tegra_bo_free(struct drm_tegra_bo *bo)
 {
-   struct drm_tegra *drm = bo->drm;
-   struct drm_gem_close args;
+struct drm_tegra *drm = bo->drm;
+struct drm_gem_close args;
 
-   if (bo->map)
-   munmap(bo->map, bo->size);
+if (bo->map)
+munmap(bo->map, bo->size);
 
-   memset(, 0, sizeof(args));
-   args.handle = bo->handle;
+memset(, 0, sizeof(args));
+args.handle = bo->handle;
 
-   drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, );
+drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, );
 
-   free(bo);
+free(bo);
 }
 
 static int drm_tegra_wrap(struct drm_tegra **drmp, int fd, bool close)
 {
-   struct drm_tegra *drm;
+struct drm_tegra *drm;
 
-   if (fd < 0 || !drmp)
-   return -EINVAL;
+if (fd < 0 || !drmp)
+return -EINVAL;
 
-   drm = calloc(1, sizeof(*drm));
-   if (!drm)
-   return -ENOMEM;
+drm = calloc(1, sizeof(*drm));
+if (!drm)
+return -ENOMEM;
 
-   drm->close = close;
-   drm->fd = fd;
+drm->close = close;
+drm->fd = fd;
 
-   *drmp = drm;
+*drmp = drm;
 
-   return 0;
+return 0;
 }
 
 drm_public int drm_tegra_new(struct drm_tegra **drmp, int fd)
 {
-   bool supported = false;
-   drmVersionPtr version;
+bool supported = false;
+drmVersionPtr version;
 
-   version = drmGetVersion(fd);
-   if (!version)
-   return -ENOMEM;
+version = drmGetVersion(fd);
+if (!version)
+return -ENOMEM;
 
-   if (!strncmp(version->name, "tegra", version->name_len))
-   supported = true;
+if (!strncmp(version->name, "tegra", version->name_len))
+supported = true;
 
-   drmFreeVersion(version);
+drmFreeVersion(version);
 
-   if (!supported)
-   return -ENOTSUP;
+if (!supported)
+return -ENOTSUP;
 
-   return drm_tegra_wrap(drmp, fd, false);
+return drm_tegra_wrap(drmp, fd, false);
 }
 
 drm_public void drm_tegra_close(struct drm_tegra *drm)
 {
-   if (!drm)
-   return;
+if (!drm)
+return;
 
-   if (drm->close)
-   close(drm->fd);
+if (drm->close)
+close(drm->fd);
 
-   free(drm);
+free(drm);
 }
 
-drm_public int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra 
*drm,
-uint32_t flags, uint32_t size)
+drm_public int
+drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
+ uint32_t flags, uint32_t size)
 {
-   struct drm_tegra_gem_create args;
-   struct drm_tegra_bo *bo;
-   int err;
+struct drm_tegra_gem_create args;
+struct drm_tegra_bo *bo;
+int err;
 
-   if (!drm || size == 0 || !bop)
-   return -EINVAL;
+if (!drm || size == 0 || !bop)
+return -EINVAL;
 
-   bo = calloc(1, sizeof(*bo));
-   if (!bo)
-   return -ENOMEM;
+bo = calloc(1, sizeof(*bo));
+if (!bo)
+return -ENOMEM;
 
-   atomic_set(>ref, 1);
-   bo->flags = flags;
-   bo->size = size;
-   bo->drm = drm;
+atomic_set(>ref, 1);
+bo->flags = flags;
+bo->size = size;
+bo->drm = drm;
 
-   memset(, 0, sizeof(args));
-   args.flags = flags;
-   args.size = size;
+memset(, 0, sizeof(args));
+args.flags = flags;
+args.size = size;
 
-   err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_CREATE, ,
- sizeof(args));
-   if (err < 0) {
-   err = -errno;
-   free(bo);
-   return err;
-   }
+err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_CREATE, ,
+  sizeof(args));
+if (err < 0) {
+err = -errno;
+free(bo);
+return 

[PATCH libdrm 00/25] Update Tegra support

2021-08-27 Thread Thierry Reding
From: Thierry Reding 

Hi all,

this is the userspace part of the kernel patches that were recently
merged into drm-next:

  https://patchwork.freedesktop.org/series/92378/

The goal is to provide a userspace implementation of the UAPI exposed by
the kernel and show its usage in some test programs that can also be
used for basic sanity testing. More complete userspace implementations
are available here:

  * https://github.com/cyndis/vaapi-tegra-driver
  * https://github.com/grate-driver/xf86-video-opentegra
  * https://github.com/grate-driver/grate

Thierry

Thierry Reding (25):
  tegra: Indent according to .editorconfig
  tegra: Remove unused IOCTL implementations
  tegra: Extract common buffer object allocation code
  tegra: Fix mmap() of GEM buffer objects
  tegra: Add flink helpers
  tegra: Add PRIME support helpers
  tegra: Make API more consistent
  tegra: Install tegra-openclose test
  tegra: Update for new UABI
  tegra: Include private.h in list of source files
  tegra: Add channel APIs
  tegra: Add job and push buffer APIs
  tegra: Add syncpoint APIs
  tests: tegra: Add helper library for tests
  tests: tegra: Add gr2d-fill test
  tests: tegra: Add syncpt-wait test
  tests: tegra: Add syncpoint timeout test
  tests: tegra: Add VIC support
  tests: tegra: Add VIC 3.0 support
  tests: tegra: Add VIC 4.0 support
  tests: tegra: Add VIC 4.1 support
  tests: tegra: Add VIC 4.2 support
  tests: tegra: Add VIC clear test
  tests: tegra: Add VIC blit test
  tests: tegra: Add VIC flip test

 include/drm/tegra_drm.h  | 429 +++--
 tegra/channel.c  | 195 
 tegra/job.c  | 187 +++
 tegra/meson.build|   7 +-
 tegra/private.h  |  85 -
 tegra/pushbuf.c  | 184 +++
 tegra/syncpt.c   | 101 ++
 tegra/tegra-symbols.txt  |  27 +-
 tegra/tegra.c| 392 ---
 tegra/tegra.h|  95 +-
 tests/tegra/.gitignore   |   3 +-
 tests/tegra/drm-test-tegra.c | 147 +
 tests/tegra/drm-test-tegra.h |  55 
 tests/tegra/drm-test.c   | 248 +++
 tests/tegra/drm-test.h   |  72 +
 tests/tegra/gr2d-fill.c  | 146 +
 tests/tegra/host1x.h |  34 ++
 tests/tegra/meson.build  |  88 +-
 tests/tegra/openclose.c  |  52 +--
 tests/tegra/syncpt-timeout.c | 163 ++
 tests/tegra/syncpt-wait.c| 151 +
 tests/tegra/vic-blit.c   | 333 +++
 tests/tegra/vic-clear.c  | 173 ++
 tests/tegra/vic-flip.c   | 333 +++
 tests/tegra/vic.c| 177 +++
 tests/tegra/vic.h| 181 +++
 tests/tegra/vic30.c  | 509 +
 tests/tegra/vic30.h  | 439 ++
 tests/tegra/vic40.c  | 412 
 tests/tegra/vic40.h  | 285 +
 tests/tegra/vic41.c  | 416 
 tests/tegra/vic41.h  | 372 ++
 tests/tegra/vic42.c  | 423 +
 tests/tegra/vic42.h  | 597 +++
 34 files changed, 7248 insertions(+), 263 deletions(-)
 create mode 100644 tegra/channel.c
 create mode 100644 tegra/job.c
 create mode 100644 tegra/pushbuf.c
 create mode 100644 tegra/syncpt.c
 create mode 100644 tests/tegra/drm-test-tegra.c
 create mode 100644 tests/tegra/drm-test-tegra.h
 create mode 100644 tests/tegra/drm-test.c
 create mode 100644 tests/tegra/drm-test.h
 create mode 100644 tests/tegra/gr2d-fill.c
 create mode 100644 tests/tegra/host1x.h
 create mode 100644 tests/tegra/syncpt-timeout.c
 create mode 100644 tests/tegra/syncpt-wait.c
 create mode 100644 tests/tegra/vic-blit.c
 create mode 100644 tests/tegra/vic-clear.c
 create mode 100644 tests/tegra/vic-flip.c
 create mode 100644 tests/tegra/vic.c
 create mode 100644 tests/tegra/vic.h
 create mode 100644 tests/tegra/vic30.c
 create mode 100644 tests/tegra/vic30.h
 create mode 100644 tests/tegra/vic40.c
 create mode 100644 tests/tegra/vic40.h
 create mode 100644 tests/tegra/vic41.c
 create mode 100644 tests/tegra/vic41.h
 create mode 100644 tests/tegra/vic42.c
 create mode 100644 tests/tegra/vic42.h

-- 
2.32.0



Re: [PATCH] MAINTAINERS: Add dri-devel for component.[hc]

2021-08-27 Thread Ezequiel Garcia
Hi Daniel,

On Thu, 26 Aug 2021 at 06:13, Daniel Vetter  wrote:
>
> dri-devel is the main user, and somehow there's been the assumption
> that component stuff is unmaintained.
>
> References: 
> https://lore.kernel.org/dri-devel/CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8...@mail.gmail.com/
> Cc: Ezequiel Garcia 
> Cc: Greg Kroah-Hartman 
> Cc: "Rafael J. Wysocki" 
> Signed-off-by: Daniel Vetter 
> ---
>  MAINTAINERS | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ac58d0032abd..7cdc19815ec4 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5707,6 +5707,11 @@ F:   Documentation/admin-guide/blockdev/
>  F: drivers/block/drbd/
>  F: lib/lru_cache.c
>
> +DRIVER COMPONENT FRAMEWORK
> +L: dri-devel@lists.freedesktop.org
> +F: drivers/base/component.c
> +F: include/linux/component.h
> +

Thanks for taking care of this, much appreciated.

Ezequiel


Re: [PATCH v1 02/14] mm: remove extra ZONE_DEVICE struct page refcount

2021-08-27 Thread Vlastimil Babka
On 8/25/21 19:49, Ralph Campbell wrote:
> 
> On 8/25/21 4:15 AM, Vlastimil Babka wrote:
>> On 8/25/21 05:48, Alex Sierra wrote:
>>> From: Ralph Campbell 
>>>
>>> ZONE_DEVICE struct pages have an extra reference count that complicates the
>>> code for put_page() and several places in the kernel that need to check the
>>> reference count to see that a page is not being used (gup, compaction,
>>> migration, etc.). Clean up the code so the reference count doesn't need to
>>> be treated specially for ZONE_DEVICE.
>> That's certainly welcome. I just wonder what was the reason to use 1 in the
>> first place and why it's no longer necessary?
> 
> I'm sure this is a long story that I don't know most of the history.
> I'm guessing that ZONE_DEVICE started out with a reference count of
> one since that is what most "normal" struct page pages start with.
> Then put_page() is used to free newly initialized struct pages to the
> slab/slob/slub page allocator.
> This made it easy to call get_page()/put_page() on ZONE_DEVICE pages
> since get_page() asserts that the caller has a reference.
> However, most drivers that create ZONE_DEVICE struct pages just insert
> a PTE into the user page tables and don't increment/decrement the
> reference count. MEMORY_DEVICE_FS_DAX used the >1 to 1 reference count
> transition to signal that a page was idle so that made put_page() a
> bit more complex. Then MEMORY_DEVICE_PRIVATE pages were added and this
> special casing of what "idle" meant got more complicated and more parts
> of mm had to check for is_device_private_page().
> My goal was to make ZONE_DEVICE struct pages reference counts be zero
> based and allocated/freed similar to the page allocator so that more
> of the mm code could be used, like THP ZONE_DEVICE pages, without special
> casing ZONE_DEVICE.

Thanks for the explanation. I was afraid there was something more fundamental
that required to catch the 2->1 refcount transition, seems like it's not. I
agree with the simplification!



[Bug 214199] Sapphire NITRO+ RX 580 4G G5 - Secondary display doesn't wake up on boot, both displays won't wake up from suspend

2021-08-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=214199

--- Comment #1 from Zeljko (ker...@zeljko.anonaddy.com) ---
Created attachment 298499
  --> https://bugzilla.kernel.org/attachment.cgi?id=298499=edit
Suspend dmesg

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

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

[Bug 214199] New: Sapphire NITRO+ RX 580 4G G5 - Secondary display doesn't wake up on boot, both displays won't wake up from suspend

2021-08-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=214199

Bug ID: 214199
   Summary: Sapphire NITRO+ RX 580 4G G5 - Secondary display
doesn't wake up on boot, both displays won't wake up
from suspend
   Product: Drivers
   Version: 2.5
Kernel Version: 5.13.12
  Hardware: All
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: ker...@zeljko.anonaddy.com
Regression: No

Created attachment 298497
  --> https://bugzilla.kernel.org/attachment.cgi?id=298497=edit
Boot dmesg

Hi! This is the first time I've tried Linux with this graphics card.

The issues are that my second monitor doesn't wake up from stand by on boot and
also both monitors won't wake up from suspend.

If I turn off the second monitor and turn it back on after boot it works fine.

Same with both monitors after the computer wakes up from suspend. I have to
turn off both of them and turn them back on.

I'm attaching both boot and suspend dmesg logs with drm.debug=0xe kernel
parameter from a fresh install of Arch Linux.

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

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

[Bug 214197] New: [Asus G713QY] RX6800M not usable after exiting Vulkan application

2021-08-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=214197

Bug ID: 214197
   Summary: [Asus G713QY] RX6800M not usable after exiting Vulkan
application
   Product: Drivers
   Version: 2.5
Kernel Version: 5.13.13
  Hardware: x86-64
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: vele...@gmail.com
Regression: No

Asus ROG Strix G17 Advantage Edition (G713QY) has hybrid-graphics with dGPU
RX6800M. After exiting any Vulkan application, it becomes unusable. Vulkaninfo
sees dGPU before Vulkan app and does not see RX6800M after.

After Vulkan app close, dmesg reports:

[  154.385749] amdgpu :03:00.0: amdgpu: RAS: optional ras ta ucode is not
available
[  154.401405] amdgpu :03:00.0: amdgpu: SECUREDISPLAY: securedisplay ta
ucode is not available
[  154.401409] amdgpu :03:00.0: amdgpu: SMU is resuming...
[  159.038150] amdgpu :03:00.0: amdgpu: message:RunDcBtc (54)  
param: 0x is timeout (no response)
[  159.038154] amdgpu :03:00.0: amdgpu: Failed to setup smc hw!
[  159.038156] [drm:amdgpu_device_ip_resume_phase2 [amdgpu]] *ERROR* resume of
IP block  failed -62
[  159.038220] amdgpu :03:00.0: amdgpu: amdgpu_device_ip_resume failed
(-62).

Using amdgpu.runpm=0 parameter fixes the issue.

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

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

[RFC PATCH 4/4] drm: Make fbdev emulation depend on FB_CORE instead of FB

2021-08-27 Thread Javier Martinez Canillas
Now that the fbdev core has been split in FB_CORE and FB, make DRM fbdev
emulation layer to just depend on the former.

This allows to disable the CONFIG_FB option if is not needed, which will
avoid the need to explicitly disable all the legacy fbdev drivers.

Signed-off-by: Javier Martinez Canillas 
---

 drivers/gpu/drm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 8fc40317f2b..7806adb02f1 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -103,7 +103,7 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
 config DRM_FBDEV_EMULATION
bool "Enable legacy fbdev support for your modesetting driver"
depends on DRM
-   depends on FB
+   depends on FB_CORE
select DRM_KMS_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
-- 
2.31.1



[RFC PATCH 3/4] fbdev: Split frame buffer support in FB and FB_CORE symbols

2021-08-27 Thread Javier Martinez Canillas
Currently the CONFIG_FB option has to be enabled even if no legacy fbdev
drivers are needed, in order to have support for a framebuffer console.

The DRM subsystem has a fbdev emulation layer, but depends on CONFIG_FB
and so it can only be enabled if that dependency is enabled as well.

That means fbdev drivers have to be explicitly disabled if users want to
enable CONFIG_FB, only to use fbcon with the DRM fbdev emulation layer.

This patch introduces a CONFIG_FB_CORE option that could be enabled just
to have the core support needed for CONFIG_DRM_FBDEV_EMULATION, allowing
CONFIG_FB to be disabled (and automatically disabling all fbdev drivers).

The fbsysfs.o object is left out of fb_core.o, because that's not needed
for KMS drivers and the DRM fbdev emulation layer.

Signed-off-by: Javier Martinez Canillas 
---

 arch/x86/Makefile |  2 +-
 arch/x86/video/Makefile   |  2 +-
 drivers/video/console/Kconfig |  2 +-
 drivers/video/fbdev/Kconfig   | 57 ++-
 drivers/video/fbdev/core/Makefile | 13 ---
 include/linux/fb.h| 14 
 6 files changed, 59 insertions(+), 31 deletions(-)

diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 44dd071d836..dc409539218 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -229,7 +229,7 @@ drivers-$(CONFIG_PCI)+= arch/x86/pci/
 # suspend and hibernation support
 drivers-$(CONFIG_PM) += arch/x86/power/
 
-drivers-$(CONFIG_FB) += arch/x86/video/
+drivers-$(CONFIG_FB_CORE) += arch/x86/video/
 
 
 # boot loader support. Several targets are kept for legacy purposes
diff --git a/arch/x86/video/Makefile b/arch/x86/video/Makefile
index 11640c11611..cb0735bd662 100644
--- a/arch/x86/video/Makefile
+++ b/arch/x86/video/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_FB)   += fbdev.o
+obj-$(CONFIG_FB_CORE)   += fbdev.o
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 840d9813b0b..0c562ed3495 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -71,7 +71,7 @@ config DUMMY_CONSOLE_ROWS
 
 config FRAMEBUFFER_CONSOLE
bool "Framebuffer Console support"
-   depends on FB && !UML
+   depends on FB_CORE && !UML
select VT_HW_CONSOLE_BINDING
select CRC32
select FONT_SUPPORT
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index d33c5cd684c..cb9e8b503a5 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -9,10 +9,8 @@ config FB_CMDLINE
 config FB_NOTIFY
bool
 
-menuconfig FB
-   tristate "Support for frame buffer devices"
-   select FB_CMDLINE
-   select FB_NOTIFY
+menuconfig FB_CORE
+   tristate "Core support for frame buffer devices"
help
  The frame buffer device provides an abstraction for the graphics
  hardware. It represents the frame buffer of some video hardware and
@@ -36,6 +34,19 @@ menuconfig FB
   for 
more
  information.
 
+ This options enables the core support for frame buffer devices.
+
+menuconfig FB
+   tristate "Support for frame buffer device drivers"
+   depends on FB_CORE
+   select FB_CMDLINE
+   select FB_NOTIFY
+   help
+ This enables support for frame buffer devices (fbdev) drivers.
+
+ The DRM subsystem provides an option to emulate fbdev devices but
+ this option allows legacy fbdev drivers to be enabled as well.
+
  Say Y here and to the driver for your graphics board below if you
  are compiling a kernel for a non-x86 architecture.
 
@@ -47,7 +58,7 @@ menuconfig FB
 
 config FIRMWARE_EDID
bool "Enable firmware EDID"
-   depends on FB
+   depends on FB_CORE
help
  This enables access to the EDID transferred from the firmware.
  On the i386, this is from the Video BIOS. Enable this if DDC/I2C
@@ -62,7 +73,7 @@ config FIRMWARE_EDID
 
 config FB_DDC
tristate
-   depends on FB
+   depends on FB_CORE
select I2C_ALGOBIT
select I2C
 
@@ -75,7 +86,7 @@ config FB_BOOT_VESA_SUPPORT
 
 config FB_CFB_FILLRECT
tristate
-   depends on FB
+   depends on FB_CORE
help
  Include the cfb_fillrect function for generic software rectangle
  filling. This is used by drivers that don't provide their own
@@ -83,7 +94,7 @@ config FB_CFB_FILLRECT
 
 config FB_CFB_COPYAREA
tristate
-   depends on FB
+   depends on FB_CORE
help
  Include the cfb_copyarea function for generic software area copying.
  This is used by drivers that don't provide their own (accelerated)
@@ -91,7 +102,7 @@ config FB_CFB_COPYAREA
 
 config FB_CFB_IMAGEBLIT
tristate
-   depends on FB
+   depends on FB_CORE
help
  Include the 

[RFC PATCH 2/4] fbdev: Move framebuffer_{alloc, release}() functions to fbmem.c

2021-08-27 Thread Javier Martinez Canillas
The framebuffer_alloc() and framebuffer_release() functions are much more
related with the functions in drivers/fbdev/core/fbmem.c than the ones in
drivers/fbdev/core/fbsysfs.c, that are only to manage sysfs attributes.

Signed-off-by: Javier Martinez Canillas 
---

 drivers/video/fbdev/core/fbmem.c   | 65 +++
 drivers/video/fbdev/core/fbsysfs.c | 71 --
 2 files changed, 65 insertions(+), 71 deletions(-)

diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index d886582c0a4..2b22e46b815 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -57,6 +57,71 @@ bool fb_center_logo __read_mostly;
 
 int fb_logo_count __read_mostly = -1;
 
+/**
+ * framebuffer_alloc - creates a new frame buffer info structure
+ *
+ * @size: size of driver private data, can be zero
+ * @dev: pointer to the device for this fb, this can be NULL
+ *
+ * Creates a new frame buffer info structure. Also reserves @size bytes
+ * for driver private data (info->par). info->par (if any) will be
+ * aligned to sizeof(long).
+ *
+ * Returns the new structure, or NULL if an error occurred.
+ *
+ */
+struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
+{
+#define BYTES_PER_LONG (BITS_PER_LONG/8)
+#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
+   int fb_info_size = sizeof(struct fb_info);
+   struct fb_info *info;
+   char *p;
+
+   if (size)
+   fb_info_size += PADDING;
+
+   p = kzalloc(fb_info_size + size, GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   info = (struct fb_info *) p;
+
+   if (size)
+   info->par = p + fb_info_size;
+
+   info->device = dev;
+   info->fbcon_rotate_hint = -1;
+
+#if IS_ENABLED(CONFIG_FB_BACKLIGHT)
+   mutex_init(>bl_curve_mutex);
+#endif
+
+   return info;
+#undef PADDING
+#undef BYTES_PER_LONG
+}
+EXPORT_SYMBOL(framebuffer_alloc);
+
+/**
+ * framebuffer_release - marks the structure available for freeing
+ *
+ * @info: frame buffer info structure
+ *
+ * Drop the reference count of the device embedded in the
+ * framebuffer info structure.
+ *
+ */
+void framebuffer_release(struct fb_info *info)
+{
+   if (!info)
+   return;
+   kfree(info->apertures);
+   kfree(info);
+}
+EXPORT_SYMBOL(framebuffer_release);
+
 static struct fb_info *get_fb_info(unsigned int idx)
 {
struct fb_info *fb_info;
diff --git a/drivers/video/fbdev/core/fbsysfs.c 
b/drivers/video/fbdev/core/fbsysfs.c
index a040d6bd6c3..2c1e3f0effe 100644
--- a/drivers/video/fbdev/core/fbsysfs.c
+++ b/drivers/video/fbdev/core/fbsysfs.c
@@ -5,12 +5,6 @@
  * Copyright (c) 2004 James Simmons 
  */
 
-/*
- * Note:  currently there's only stubs for framebuffer_alloc and
- * framebuffer_release here.  The reson for that is that until all drivers
- * are converted to use it a sysfsification will open OOPSable races.
- */
-
 #include 
 #include 
 #include 
@@ -20,71 +14,6 @@
 
 #define FB_SYSFS_FLAG_ATTR 1
 
-/**
- * framebuffer_alloc - creates a new frame buffer info structure
- *
- * @size: size of driver private data, can be zero
- * @dev: pointer to the device for this fb, this can be NULL
- *
- * Creates a new frame buffer info structure. Also reserves @size bytes
- * for driver private data (info->par). info->par (if any) will be
- * aligned to sizeof(long).
- *
- * Returns the new structure, or NULL if an error occurred.
- *
- */
-struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
-{
-#define BYTES_PER_LONG (BITS_PER_LONG/8)
-#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
-   int fb_info_size = sizeof(struct fb_info);
-   struct fb_info *info;
-   char *p;
-
-   if (size)
-   fb_info_size += PADDING;
-
-   p = kzalloc(fb_info_size + size, GFP_KERNEL);
-
-   if (!p)
-   return NULL;
-
-   info = (struct fb_info *) p;
-
-   if (size)
-   info->par = p + fb_info_size;
-
-   info->device = dev;
-   info->fbcon_rotate_hint = -1;
-
-#if IS_ENABLED(CONFIG_FB_BACKLIGHT)
-   mutex_init(>bl_curve_mutex);
-#endif
-
-   return info;
-#undef PADDING
-#undef BYTES_PER_LONG
-}
-EXPORT_SYMBOL(framebuffer_alloc);
-
-/**
- * framebuffer_release - marks the structure available for freeing
- *
- * @info: frame buffer info structure
- *
- * Drop the reference count of the device embedded in the
- * framebuffer info structure.
- *
- */
-void framebuffer_release(struct fb_info *info)
-{
-   if (!info)
-   return;
-   kfree(info->apertures);
-   kfree(info);
-}
-EXPORT_SYMBOL(framebuffer_release);
-
 static int activate(struct fb_info *fb_info, struct fb_var_screeninfo *var)
 {
int err;
-- 
2.31.1



[RFC PATCH 1/4] fbdev: Rename fb_*_device() functions names to match what they do

2021-08-27 Thread Javier Martinez Canillas
The fb_init_device() and fb_cleanup_device() functions only register and
unregister sysfs attributes as their initialization and cleanup logic.
Let's rename these functions to better match what they actually do.

There's only a call to dev_set_drvdata() that's not related to the sysfs
registration, so move it to the do_register_framebuffer() function which
is where the device is created.

Signed-off-by: Javier Martinez Canillas 
---

 drivers/video/fbdev/core/fbmem.c   | 8 +---
 drivers/video/fbdev/core/fbsysfs.c | 6 ++
 include/linux/fb.h | 4 ++--
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index 71fb710f1ce..d886582c0a4 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -1602,8 +1602,10 @@ static int do_register_framebuffer(struct fb_info 
*fb_info)
/* Not fatal */
printk(KERN_WARNING "Unable to create device for framebuffer 
%d; errno = %ld\n", i, PTR_ERR(fb_info->dev));
fb_info->dev = NULL;
-   } else
-   fb_init_device(fb_info);
+   } else {
+   dev_set_drvdata(fb_info->dev, fb_info);
+   fb_register_sysfs(fb_info);
+   }
 
if (fb_info->pixmap.addr == NULL) {
fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
@@ -1701,7 +1703,7 @@ static void do_unregister_framebuffer(struct fb_info 
*fb_info)
fb_destroy_modelist(_info->modelist);
registered_fb[fb_info->node] = NULL;
num_registered_fb--;
-   fb_cleanup_device(fb_info);
+   fb_unregister_sysfs(fb_info);
 #ifdef CONFIG_GUMSTIX_AM200EPD
{
struct fb_event event;
diff --git a/drivers/video/fbdev/core/fbsysfs.c 
b/drivers/video/fbdev/core/fbsysfs.c
index 65dae05fff8..a040d6bd6c3 100644
--- a/drivers/video/fbdev/core/fbsysfs.c
+++ b/drivers/video/fbdev/core/fbsysfs.c
@@ -507,12 +507,10 @@ static struct device_attribute device_attrs[] = {
 #endif
 };
 
-int fb_init_device(struct fb_info *fb_info)
+int fb_register_sysfs(struct fb_info *fb_info)
 {
int i, error = 0;
 
-   dev_set_drvdata(fb_info->dev, fb_info);
-
fb_info->class_flag |= FB_SYSFS_FLAG_ATTR;
 
for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
@@ -531,7 +529,7 @@ int fb_init_device(struct fb_info *fb_info)
return 0;
 }
 
-void fb_cleanup_device(struct fb_info *fb_info)
+void fb_unregister_sysfs(struct fb_info *fb_info)
 {
unsigned int i;
 
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 5950f8f5dc7..96111248a25 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -689,8 +689,8 @@ static inline bool fb_be_math(struct fb_info *info)
 /* drivers/video/fbsysfs.c */
 extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
 extern void framebuffer_release(struct fb_info *info);
-extern int fb_init_device(struct fb_info *fb_info);
-extern void fb_cleanup_device(struct fb_info *head);
+extern int fb_register_sysfs(struct fb_info *fb_info);
+extern void fb_unregister_sysfs(struct fb_info *head);
 extern void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 
max);
 
 /* drivers/video/fbmon.c */
-- 
2.31.1



[RFC PATCH 0/4] Allow to use DRM fbdev emulation layer with CONFIG_FB disabled

2021-08-27 Thread Javier Martinez Canillas
This patch series splits the fbdev core support in two different Kconfig
symbols: FB and FB_CORE. The motivation for this is to allow CONFIG_FB to
be disabled, while still using fbcon with the DRM fbdev emulation layer.

The reason for doing this is that now with simpledrm we could just boot
with simpledrm -> real DRM driver, without needing any legacy fbdev driver
(e.g: efifb or simplefb) even for the early console.

We want to do that in the Fedora kernel, but currently need to keep option
CONFIG_FB enabled and all fbdev drivers explicitly disabled, which makes
the configuration harder to maintain.

It is a RFC because I'm not that familiar with the fbdev core, but I have
tested and works with CONFIG_DRM_FBDEV_EMULATION=y and CONFIG_FB disabled.
This config automatically disables all the fbdev drivers that is our goal.

Patch 1/4 is just a clean up, patch 2/4 moves a couple of functions out of
fbsysfs.o, that are not related to sysfs attributes creation and finally
patch 3/4 makes the fbdev split that is mentioned above.

Patch 4/4 makes the DRM fbdev emulation depend on the new FB_CORE symbol
instead of FB. This could be done as a follow-up but for completeness is
also included in this series.

Best regards,
Javier


Javier Martinez Canillas (4):
  fbdev: Rename fb_*_device() functions names to match what they do
  fbdev: Move framebuffer_{alloc,release}() functions to fbmem.c
  fbdev: Split frame buffer support in FB and FB_CORE symbols
  drm: Make fbdev emulation depend on FB_CORE instead of FB

 arch/x86/Makefile  |  2 +-
 arch/x86/video/Makefile|  2 +-
 drivers/gpu/drm/Kconfig|  2 +-
 drivers/video/console/Kconfig  |  2 +-
 drivers/video/fbdev/Kconfig| 57 +-
 drivers/video/fbdev/core/Makefile  | 13 +++--
 drivers/video/fbdev/core/fbmem.c   | 73 ++--
 drivers/video/fbdev/core/fbsysfs.c | 77 +-
 include/linux/fb.h | 18 ++-
 9 files changed, 134 insertions(+), 112 deletions(-)

-- 
2.31.1



  1   2   >