Re: [PATCH] drm/i915/guc: Use drm_err instead of pr_err

2022-06-10 Thread kernel test robot
Hi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.19-rc1]
[also build test ERROR on next-20220610]
[cannot apply to drm-intel/for-linux-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/intel-lab-lkp/linux/commits/John-C-Harrison-Intel-com/drm-i915-guc-Use-drm_err-instead-of-pr_err/20220608-055315
base:f2906aa863381afb0015a9eb7fefad885d4e5a56
config: x86_64-allyesconfig 
(https://download.01.org/0day-ci/archive/20220611/202206111316.zdpqcjgj-...@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-3) 11.3.0
reproduce (this is a W=1 build):
# 
https://github.com/intel-lab-lkp/linux/commit/66426324c5bb1a53dd401b7d781c3c9c58f163d5
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
John-C-Harrison-Intel-com/drm-i915-guc-Use-drm_err-instead-of-pr_err/20220608-055315
git checkout 66426324c5bb1a53dd401b7d781c3c9c58f163d5
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

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

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c:4956:
   drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c: In function 
'__intel_guc_multi_lrc_basic':
>> drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c:121:17: error: implicit 
>> declaration of function 'drm_debug'; did you mean 'pr_debug'? 
>> [-Werror=implicit-function-declaration]
 121 | drm_debug(>i915->drm, "Not enough engines in 
class: %d", class);
 | ^
 | pr_debug
   cc1: all warnings being treated as errors


vim +121 drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c

   109  
   110  static int __intel_guc_multi_lrc_basic(struct intel_gt *gt, unsigned 
int class)
   111  {
   112  struct intel_context *parent;
   113  struct i915_request *rq;
   114  int ret;
   115  
   116  parent = multi_lrc_create_parent(gt, class, 0);
   117  if (IS_ERR(parent)) {
   118  drm_err(>i915->drm, "Failed creating contexts: 
%ld", PTR_ERR(parent));
   119  return PTR_ERR(parent);
   120  } else if (!parent) {
 > 121  drm_debug(>i915->drm, "Not enough engines in class: 
 > %d", class);
   122  return 0;
   123  }
   124  
   125  rq = multi_lrc_nop_request(parent);
   126  if (IS_ERR(rq)) {
   127  ret = PTR_ERR(rq);
   128  drm_err(>i915->drm, "Failed creating requests: %d", 
ret);
   129  goto out;
   130  }
   131  
   132  ret = intel_selftest_wait_for_rq(rq);
   133  if (ret)
   134  drm_err(>i915->drm, "Failed waiting on request: 
%d", ret);
   135  
   136  i915_request_put(rq);
   137  
   138  if (ret >= 0) {
   139  ret = intel_gt_wait_for_idle(gt, HZ * 5);
   140  if (ret < 0)
   141  drm_err(>i915->drm, "GT failed to idle: 
%d\n", ret);
   142  }
   143  
   144  out:
   145  multi_lrc_context_unpin(parent);
   146  multi_lrc_context_put(parent);
   147  return ret;
   148  }
   149  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp


[Bug 210301] *ERROR* IB test failed on gfx (-110) on Ryzen 4750u

2022-06-10 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=210301

--- Comment #4 from ramast (m...@ramast.me) ---
After more log review it seems I had two problems:
One related to have two graphics card and that's the one resulting in the
"amdgpu_ib_ring_tests" error

https://pastebin.com/Eu7PF3en

Then after disabling the Dedicated graphics card, I got the error in my
previous comment. After removing iommu_v2 I am finally error free.

-- 
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 210301] *ERROR* IB test failed on gfx (-110) on Ryzen 4750u

2022-06-10 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=210301

--- Comment #3 from ramast (m...@ramast.me) ---
I think mine could be a different problem but I'll paste the output here anyway
in case it help anyone. Mine consistently happen the second time my PC goes
into sleep mode (S3).

https://pastebin.com/DZ8rZuHq

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

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

[PATCH 2/2] drm/i915/gt: Cleanup interface for MCR operations

2022-06-10 Thread Matt Roper
Let's replace the assortment of intel_gt_* and intel_uncore_* functions
that operate on MCR registers with a cleaner set of interfaces:

  * intel_gt_mcr_read -- unicast read from specific instance
  * intel_gt_mcr_read_any[_fw] -- unicast read from any non-terminated
instance
  * intel_gt_mcr_unicast_write -- unicast write to specific instance
  * intel_gt_mcr_multicast_write[_fw] -- multicast write to all instances

We'll also replace the historic "slice" and "subslice" terminology with
"group" and "instance" to match the documentation for more recent
platforms; these days MCR steering applies to more types of replication
than just slice/subslice.

Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c  |   2 +-
 drivers/gpu/drm/i915/gt/intel_engine_cs.c   |  33 ++-
 drivers/gpu/drm/i915/gt/intel_gt_debugfs.c  |   2 +-
 drivers/gpu/drm/i915/gt/intel_gt_mcr.c  | 225 +++-
 drivers/gpu/drm/i915/gt/intel_gt_mcr.h  |  43 ++--
 drivers/gpu/drm/i915/gt/intel_region_lmem.c |   4 +-
 drivers/gpu/drm/i915/gt/intel_workarounds.c |   8 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c  |   2 +-
 8 files changed, 174 insertions(+), 145 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index da30503d3ca2..fa54823d1219 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -835,7 +835,7 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, 
u16 type,
} else {
resource_size_t lmem_range;
 
-   lmem_range = intel_gt_read_register(>gt0, 
XEHPSDV_TILE0_ADDR_RANGE) & 0x;
+   lmem_range = intel_gt_mcr_read_any(>gt0, 
XEHPSDV_TILE0_ADDR_RANGE) & 0x;
lmem_size = lmem_range >> XEHPSDV_TILE_LMEM_RANGE_SHIFT;
lmem_size *= SZ_1G;
}
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 244af1bdb7db..136cc44c3deb 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -1428,14 +1428,6 @@ void intel_engine_cancel_stop_cs(struct intel_engine_cs 
*engine)
ENGINE_WRITE_FW(engine, RING_MI_MODE, _MASKED_BIT_DISABLE(STOP_RING));
 }
 
-static u32
-read_subslice_reg(const struct intel_engine_cs *engine,
- int slice, int subslice, i915_reg_t reg)
-{
-   return intel_uncore_read_with_mcr_steering(engine->uncore, reg,
-  slice, subslice);
-}
-
 /* NB: please notice the memset */
 void intel_engine_get_instdone(const struct intel_engine_cs *engine,
   struct intel_instdone *instdone)
@@ -1469,28 +1461,33 @@ void intel_engine_get_instdone(const struct 
intel_engine_cs *engine,
if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50)) {
for_each_instdone_gslice_dss_xehp(i915, sseu, iter, 
slice, subslice) {
instdone->sampler[slice][subslice] =
-   read_subslice_reg(engine, slice, 
subslice,
- 
GEN7_SAMPLER_INSTDONE);
+   intel_gt_mcr_read(engine->gt,
+ GEN7_SAMPLER_INSTDONE,
+ slice, subslice);
instdone->row[slice][subslice] =
-   read_subslice_reg(engine, slice, 
subslice,
- GEN7_ROW_INSTDONE);
+   intel_gt_mcr_read(engine->gt,
+ GEN7_ROW_INSTDONE,
+ slice, subslice);
}
} else {
for_each_instdone_slice_subslice(i915, sseu, slice, 
subslice) {
instdone->sampler[slice][subslice] =
-   read_subslice_reg(engine, slice, 
subslice,
- 
GEN7_SAMPLER_INSTDONE);
+   intel_gt_mcr_read(engine->gt,
+ GEN7_SAMPLER_INSTDONE,
+ slice, subslice);
instdone->row[slice][subslice] =
-   read_subslice_reg(engine, slice, 
subslice,
- GEN7_ROW_INSTDONE);
+   intel_gt_mcr_read(engine->gt,
+ GEN7_ROW_INSTDONE,
+ slice, subslice);

[PATCH 1/2] drm/i915/gt: Move multicast register handling to a dedicated file

2022-06-10 Thread Matt Roper
Handling of multicast/replicated registers is spread across intel_gt.c
and intel_uncore.c today.  As multicast handling and the related
steering logic gets more complicated with the addition of new platforms
and new rules it makes sense to centralize it all in one place.

For now the existing functions have been moved to the new .c/.h as-is.
Function renames and updates to operate in a more consistent manner will
be done in subsequent patches.

Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/Makefile   |   1 +
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c  |   1 +
 drivers/gpu/drm/i915/gt/intel_engine_cs.c   |   3 +-
 drivers/gpu/drm/i915/gt/intel_gt.c  | 297 +
 drivers/gpu/drm/i915/gt/intel_gt.h  |  15 -
 drivers/gpu/drm/i915/gt/intel_gt_debugfs.c  |   1 +
 drivers/gpu/drm/i915/gt/intel_gt_mcr.c  | 448 
 drivers/gpu/drm/i915/gt/intel_gt_mcr.h  |  37 ++
 drivers/gpu/drm/i915/gt/intel_region_lmem.c |   1 +
 drivers/gpu/drm/i915/gt/intel_workarounds.c |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c  |   1 +
 drivers/gpu/drm/i915/i915_drv.h |   2 -
 drivers/gpu/drm/i915/intel_uncore.c | 112 -
 drivers/gpu/drm/i915/intel_uncore.h |   8 -
 14 files changed, 495 insertions(+), 433 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gt_mcr.c
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gt_mcr.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index d2b18f03a33c..08f5d0d6e83a 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -103,6 +103,7 @@ gt-y += \
gt/intel_gt_debugfs.o \
gt/intel_gt_engines_debugfs.o \
gt/intel_gt_irq.o \
+   gt/intel_gt_mcr.o \
gt/intel_gt_pm.o \
gt/intel_gt_pm_debugfs.o \
gt/intel_gt_pm_irq.o \
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 47b5e0e342ab..da30503d3ca2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -13,6 +13,7 @@
 #include "gem/i915_gem_lmem.h"
 #include "gem/i915_gem_region.h"
 #include "gt/intel_gt.h"
+#include "gt/intel_gt_mcr.h"
 #include "gt/intel_region_lmem.h"
 #include "i915_drv.h"
 #include "i915_gem_stolen.h"
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index f0acf8518a51..244af1bdb7db 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -21,8 +21,9 @@
 #include "intel_engine_user.h"
 #include "intel_execlists_submission.h"
 #include "intel_gt.h"
-#include "intel_gt_requests.h"
+#include "intel_gt_mcr.h"
 #include "intel_gt_pm.h"
+#include "intel_gt_requests.h"
 #include "intel_lrc.h"
 #include "intel_lrc_reg.h"
 #include "intel_reset.h"
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index f33290358c51..be9877c4b496 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -17,6 +17,7 @@
 #include "intel_gt_clock_utils.h"
 #include "intel_gt_debugfs.h"
 #include "intel_gt_gmch.h"
+#include "intel_gt_mcr.h"
 #include "intel_gt_pm.h"
 #include "intel_gt_regs.h"
 #include "intel_gt_requests.h"
@@ -102,107 +103,13 @@ int intel_gt_assign_ggtt(struct intel_gt *gt)
return gt->ggtt ? 0 : -ENOMEM;
 }
 
-static const char * const intel_steering_types[] = {
-   "L3BANK",
-   "MSLICE",
-   "LNCF",
-   "INSTANCE 0",
-};
-
-static const struct intel_mmio_range icl_l3bank_steering_table[] = {
-   { 0x00B100, 0x00B3FF },
-   {},
-};
-
-static const struct intel_mmio_range xehpsdv_mslice_steering_table[] = {
-   { 0x004000, 0x004AFF },
-   { 0x00C800, 0x00CFFF },
-   { 0x00DD00, 0x00DDFF },
-   { 0x00E900, 0x00 }, /* 0xEA00 - OxEFFF is unused */
-   {},
-};
-
-static const struct intel_mmio_range xehpsdv_lncf_steering_table[] = {
-   { 0x00B000, 0x00B0FF },
-   { 0x00D800, 0x00D8FF },
-   {},
-};
-
-static const struct intel_mmio_range dg2_lncf_steering_table[] = {
-   { 0x00B000, 0x00B0FF },
-   { 0x00D880, 0x00D8FF },
-   {},
-};
-
-/*
- * We have several types of MCR registers on PVC where steering to (0,0)
- * will always provide us with a non-terminated value.  We'll stick them
- * all in the same table for simplicity.
- */
-static const struct intel_mmio_range pvc_instance0_steering_table[] = {
-   { 0x004000, 0x004AFF }, /* HALF-BSLICE */
-   { 0x008800, 0x00887F }, /* CC */
-   { 0x008A80, 0x008AFF }, /* TILEPSMI */
-   { 0x00B000, 0x00B0FF }, /* HALF-BSLICE */
-   { 0x00B100, 0x00B3FF }, /* L3BANK */
-   { 0x00C800, 0x00CFFF }, /* HALF-BSLICE */
-   { 0x00D800, 0x00D8FF }, /* HALF-BSLICE */
-   { 0x00DD00, 0x00DDFF }, /* BSLICE */
-   { 0x00E900, 0x00E9FF }, /* 

[PATCH 0/2] i915: Extract, polish, and document multicast handling

2022-06-10 Thread Matt Roper
Multicast/replicated (MCR) registers on Intel hardware are a purely
GT-specific concept.  Rather than leaving MCR register handling spread
across several places throughout the driver (intel_uncore.c, intel_gt.c,
etc.) with confusing combinations of handler functions living in
different namespaces, let's consolidate it all into a single place
(intel_gt_mcr.c) and provide a more consistent and clearly-documented
interface for the rest of the driver to access such registers:

 * intel_gt_mcr_read -- unicast read from specific instance
 * intel_gt_mcr_read_any[_fw] -- unicast read from any non-terminated
   instance
 * intel_gt_mcr_unicast_write -- unicast write to specific instance
 * intel_gt_mcr_multicast_write[_fw] -- multicast write to all instances

Matt Roper (2):
  drm/i915/gt: Move multicast register handling to a dedicated file
  drm/i915/gt: Cleanup interface for MCR operations

 drivers/gpu/drm/i915/Makefile   |   1 +
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c  |   3 +-
 drivers/gpu/drm/i915/gt/intel_engine_cs.c   |  36 +-
 drivers/gpu/drm/i915/gt/intel_gt.c  | 297 +---
 drivers/gpu/drm/i915/gt/intel_gt.h  |  15 -
 drivers/gpu/drm/i915/gt/intel_gt_debugfs.c  |   3 +-
 drivers/gpu/drm/i915/gt/intel_gt_mcr.c  | 483 
 drivers/gpu/drm/i915/gt/intel_gt_mcr.h  |  34 ++
 drivers/gpu/drm/i915/gt/intel_region_lmem.c |   5 +-
 drivers/gpu/drm/i915/gt/intel_workarounds.c |   9 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c  |   3 +-
 drivers/gpu/drm/i915/i915_drv.h |   2 -
 drivers/gpu/drm/i915/intel_uncore.c | 112 -
 drivers/gpu/drm/i915/intel_uncore.h |   8 -
 14 files changed, 551 insertions(+), 460 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gt_mcr.c
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gt_mcr.h

-- 
2.35.3



[PATCH] drm/i915/guc/slpc: Add a new SLPC selftest

2022-06-10 Thread Vinay Belgaumkar
This test will validate we can achieve actual frequency of RP0. Pcode
grants frequencies based on what GuC is requesting. However, thermal
throttling can limit what is being granted. Add a test to request for
max, but don't fail the test if RP0 is not granted due to throttle
reasons.

Also optimize the selftest by using a common run_test function to avoid
code duplication. Rename the "clamp" tests to vary_max_freq and vary_min_freq.

v2: Fix compile warning

Fixes 8ee2c227822e ("drm/i915/guc/slpc: Add SLPC selftest")
Signed-off-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/selftest_slpc.c | 323 
 1 file changed, 158 insertions(+), 165 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c 
b/drivers/gpu/drm/i915/gt/selftest_slpc.c
index b768cea5943d..099129aae9a5 100644
--- a/drivers/gpu/drm/i915/gt/selftest_slpc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c
@@ -8,6 +8,11 @@
 #define delay_for_h2g() usleep_range(H2G_DELAY, H2G_DELAY + 1)
 #define FREQUENCY_REQ_UNIT DIV_ROUND_CLOSEST(GT_FREQUENCY_MULTIPLIER, \
  GEN9_FREQ_SCALER)
+enum test_type {
+   VARY_MIN,
+   VARY_MAX,
+   MAX_GRANTED
+};
 
 static int slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 freq)
 {
@@ -36,147 +41,120 @@ static int slpc_set_max_freq(struct intel_guc_slpc *slpc, 
u32 freq)
return ret;
 }
 
-static int live_slpc_clamp_min(void *arg)
+static int vary_max_freq(struct intel_guc_slpc *slpc, struct intel_rps *rps,
+ u32 *max_act_freq)
 {
-   struct drm_i915_private *i915 = arg;
-   struct intel_gt *gt = to_gt(i915);
-   struct intel_guc_slpc *slpc = >uc.guc.slpc;
-   struct intel_rps *rps = >rps;
-   struct intel_engine_cs *engine;
-   enum intel_engine_id id;
-   struct igt_spinner spin;
+   u32 step, max_freq, req_freq;
+   u32 act_freq;
u32 slpc_min_freq, slpc_max_freq;
int err = 0;
 
-   if (!intel_uc_uses_guc_slpc(>uc))
-   return 0;
-
-   if (igt_spinner_init(, gt))
-   return -ENOMEM;
+   slpc_min_freq = slpc->min_freq;
+   slpc_max_freq = slpc->rp0_freq;
 
-   if (intel_guc_slpc_get_max_freq(slpc, _max_freq)) {
-   pr_err("Could not get SLPC max freq\n");
-   return -EIO;
-   }
-
-   if (intel_guc_slpc_get_min_freq(slpc, _min_freq)) {
-   pr_err("Could not get SLPC min freq\n");
-   return -EIO;
-   }
-
-   if (slpc_min_freq == slpc_max_freq) {
-   pr_err("Min/Max are fused to the same value\n");
-   return -EINVAL;
-   }
-
-   intel_gt_pm_wait_for_idle(gt);
-   intel_gt_pm_get(gt);
-   for_each_engine(engine, gt, id) {
-   struct i915_request *rq;
-   u32 step, min_freq, req_freq;
-   u32 act_freq, max_act_freq;
-
-   if (!intel_engine_can_store_dword(engine))
-   continue;
+   /* Go from max to min in 5 steps */
+   step = (slpc_max_freq - slpc_min_freq) / NUM_STEPS;
+   *max_act_freq = slpc_min_freq;
+   for (max_freq = slpc_max_freq; max_freq > slpc_min_freq;
+   max_freq -= step) {
+   err = slpc_set_max_freq(slpc, max_freq);
+   if (err)
+   break;
 
-   /* Go from min to max in 5 steps */
-   step = (slpc_max_freq - slpc_min_freq) / NUM_STEPS;
-   max_act_freq = slpc_min_freq;
-   for (min_freq = slpc_min_freq; min_freq < slpc_max_freq;
-   min_freq += step) {
-   err = slpc_set_min_freq(slpc, min_freq);
-   if (err)
-   break;
-
-   st_engine_heartbeat_disable(engine);
-
-   rq = igt_spinner_create_request(,
-   engine->kernel_context,
-   MI_NOOP);
-   if (IS_ERR(rq)) {
-   err = PTR_ERR(rq);
-   st_engine_heartbeat_enable(engine);
-   break;
-   }
+   req_freq = intel_rps_read_punit_req_frequency(rps);
 
-   i915_request_add(rq);
+   /* GuC requests freq in multiples of 50/3 MHz */
+   if (req_freq > (max_freq + FREQUENCY_REQ_UNIT)) {
+   pr_err("SWReq is %d, should be at most %d\n", req_freq,
+   max_freq + FREQUENCY_REQ_UNIT);
+   err = -EINVAL;
+   }
 
-   if (!igt_wait_for_spinner(, rq)) {
-   pr_err("%s: Spinner did not start\n",
-  engine->name);
-   igt_spinner_end();

Re: [PATCH] drm/msm/dsi: Use single function for reset

2022-06-10 Thread Abhinav Kumar




On 6/10/2022 3:02 PM, Luca Weiss wrote:

From: Vladimir Lypak 

There is currently two function for performing reset: dsi_sw_reset and
dsi_sw_reset_restore. Only difference betwean those is that latter one

betwean --> between

assumes that DSI controller is enabled. In contrary former one assumes
that controller is disabled and executed during power-on. However this
assumtion is not true mobile devices which have boot splash set up by
boot-loader.

This patch removes dsi_sw_reset_restore and makes dsi_sw_reset disable
DSI controller during reset sequence if it's enabled.

Signed-off-by: Vladimir Lypak 
Signed-off-by: Luca Weiss 


Otherwise, looks good to me,

Reviewed-by: Abhinav Kumar 

---
  drivers/gpu/drm/msm/dsi/dsi_host.c | 48 +-
  1 file changed, 21 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index a95d5df52653..bab2634ebd11 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1080,12 +1080,32 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
  
  static void dsi_sw_reset(struct msm_dsi_host *msm_host)

  {
+   u32 ctrl;
+
+   ctrl = dsi_read(msm_host, REG_DSI_CTRL);
+
+   if (ctrl & DSI_CTRL_ENABLE) {
+   dsi_write(msm_host, REG_DSI_CTRL, ctrl & ~DSI_CTRL_ENABLE);
+   /*
+* dsi controller need to be disabled before
+* clocks turned on
+*/
+   wmb();
+   }
+
dsi_write(msm_host, REG_DSI_CLK_CTRL, DSI_CLK_CTRL_ENABLE_CLKS);
wmb(); /* clocks need to be enabled before reset */
  
+	/* dsi controller can only be reset while clocks are running */

dsi_write(msm_host, REG_DSI_RESET, 1);
msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */
dsi_write(msm_host, REG_DSI_RESET, 0);
+   wmb(); /* controller out of reset */
+
+   if (ctrl & DSI_CTRL_ENABLE) {
+   dsi_write(msm_host, REG_DSI_CTRL, ctrl);
+   wmb();  /* make sure dsi controller enabled again */
+   }
  }
  
  static void dsi_op_mode_config(struct msm_dsi_host *msm_host,

@@ -1478,32 +1498,6 @@ static int dsi_cmds2buf_tx(struct msm_dsi_host *msm_host,
return len;
  }
  
-static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host)

-{
-   u32 data0, data1;
-
-   data0 = dsi_read(msm_host, REG_DSI_CTRL);
-   data1 = data0;
-   data1 &= ~DSI_CTRL_ENABLE;
-   dsi_write(msm_host, REG_DSI_CTRL, data1);
-   /*
-* dsi controller need to be disabled before
-* clocks turned on
-*/
-   wmb();
-
-   dsi_write(msm_host, REG_DSI_CLK_CTRL, DSI_CLK_CTRL_ENABLE_CLKS);
-   wmb();  /* make sure clocks enabled */
-
-   /* dsi controller can only be reset while clocks are running */
-   dsi_write(msm_host, REG_DSI_RESET, 1);
-   msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */
-   dsi_write(msm_host, REG_DSI_RESET, 0);
-   wmb();  /* controller out of reset */
-   dsi_write(msm_host, REG_DSI_CTRL, data0);
-   wmb();  /* make sure dsi controller enabled again */
-}
-
  static void dsi_hpd_worker(struct work_struct *work)
  {
struct msm_dsi_host *msm_host =
@@ -1520,7 +1514,7 @@ static void dsi_err_worker(struct work_struct *work)
  
  	pr_err_ratelimited("%s: status=%x\n", __func__, status);

if (status & DSI_ERR_STATE_MDP_FIFO_UNDERFLOW)
-   dsi_sw_reset_restore(msm_host);
+   dsi_sw_reset(msm_host);
  
  	/* It is safe to clear here because error irq is disabled. */

msm_host->err_work_state = 0;


Re: [PATCH 1/2] drm/msm/mdp5: Add perf data for MDP v1.16

2022-06-10 Thread Dmitry Baryshkov

On 11/06/2022 01:53, Luca Weiss wrote:

From: Vladimir Lypak 

Add the perf data for the mdp found in msm8953.

Signed-off-by: Vladimir Lypak 
Signed-off-by: Luca Weiss 


Reviewed-by: Dmitry Baryshkov 


---
  drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
index 1bf9ff5dbabc..b17f868ffca8 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
@@ -837,6 +837,11 @@ static const struct mdp5_cfg_hw msm8x53_config = {
[2] = INTF_DSI,
},
},
+   .perf = {
+   .ab_inefficiency = 100,
+   .ib_inefficiency = 200,
+   .clk_inefficiency = 105
+   },
.max_clk = 4,
  };
  



--
With best wishes
Dmitry


[PATCH 1/3] iosys-map: Add per-word read

2022-06-10 Thread Lucas De Marchi
Instead of always falling back to memcpy_fromio() for any size, prefer
using read{b,w,l}(). When reading struct members it's common to read
individual integer variables individually. Going through memcpy_fromio()
for each of them poses a high penalty.

Employ a similar trick as __seqprop() by using _Generic() to generate
only the specific call based on a type-compatible variable.

For a pariticular i915 workload producing GPU context switches,
__get_engine_usage_record() is particularly hot since the engine usage
is read from device local memory with dgfx, possibly multiple times
since it's racy. Test execution time for this test shows a ~12.5%
improvement with DG2:

Before:
nrepeats = 1000; min = 7.63243e+06; max = 1.01817e+07;
median = 9.52548e+06; var = 526149;
After:
nrepeats = 1000; min = 7.03402e+06; max = 8.8832e+06;
median = 8.33955e+06; var = 333113;

Other things attempted that didn't prove very useful:
1) Change the _Generic() on x86 to just dereference the memory address
2) Change __get_engine_usage_record() to do just 1 read per loop,
   comparing with the previous value read
3) Change __get_engine_usage_record() to access the fields directly as it
   was before the conversion to iosys-map

(3) did gave a small improvement (~3%), but doesn't seem to scale well
to other similar cases in the driver.

Additional test by Chris Wilson using gem_create from igt with some
changes to track object creation time. This happens to accidentally
stress this code path:

Pre iosys_map conversion of engine busyness:
lmem0: Creating262144 4KiB objects took 59274.2ms

Unpatched:
lmem0: Creating262144 4KiB objects took 108830.2ms

With readl (this patch):
lmem0: Creating262144 4KiB objects took 61348.6ms

s/readl/READ_ONCE/
lmem0: Creating262144 4KiB objects took 61333.2ms

So we do take a little bit more time than before the conversion, but
that is due to other factors: bringing the READ_ONCE back would be as
good as just doing this conversion.

Signed-off-by: Lucas De Marchi 
---
 include/linux/iosys-map.h | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index e69a002d5aa4..cd28c7a1b79c 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -333,6 +333,20 @@ static inline void iosys_map_memset(struct iosys_map *dst, 
size_t offset,
memset(dst->vaddr + offset, value, len);
 }
 
+#ifdef CONFIG_64BIT
+#define __iosys_map_rd_io_u64_case(val_, vaddr_iomem_) \
+   u64: val_ = readq(vaddr_iomem_),
+#else
+#define __iosys_map_rd_io_u64_case(val_, vaddr_iomem_)
+#endif
+
+#define __iosys_map_rd_io(val__, vaddr_iomem__, type__) _Generic(val__,
\
+   u8: val__ = readb(vaddr_iomem__),   \
+   u16: val__ = readw(vaddr_iomem__),  \
+   u32: val__ = readl(vaddr_iomem__),  \
+   __iosys_map_rd_io_u64_case(val__, vaddr_iomem__)\
+   default: memcpy_fromio(&(val__), vaddr_iomem__, sizeof(val__)))
+
 /**
  * iosys_map_rd - Read a C-type value from the iosys_map
  *
@@ -346,10 +360,14 @@ static inline void iosys_map_memset(struct iosys_map 
*dst, size_t offset,
  * Returns:
  * The value read from the mapping.
  */
-#define iosys_map_rd(map__, offset__, type__) ({   \
-   type__ val; \
-   iosys_map_memcpy_from(, map__, offset__, sizeof(val));  \
-   val;\
+#define iosys_map_rd(map__, offset__, type__) ({   
\
+   type__ val; 
\
+   if ((map__)->is_iomem) {
\
+   __iosys_map_rd_io(val, (map__)->vaddr_iomem + offset__, 
type__);\
+   } else {
\
+   memcpy(, (map__)->vaddr + offset__, sizeof(val));   
\
+   }   
\
+   val;
\
 })
 
 /**
-- 
2.36.1



[PATCH 3/3] iosys-map: Fix typo in documentation

2022-06-10 Thread Lucas De Marchi
It's one argument, vaddr_iomem, not 2 (vaddr and _iomem).

Signed-off-by: Lucas De Marchi 
---
 include/linux/iosys-map.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index 793e5cd50dbf..d092d30f5812 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -23,7 +23,7 @@
  * memcpy(vaddr, src, len);
  *
  * void *vaddr_iomem = ...; // pointer to I/O memory
- * memcpy_toio(vaddr, _iomem, src, len);
+ * memcpy_toio(vaddr_iomem, src, len);
  *
  * The user of such pointer may not have information about the mapping of that
  * region or may want to have a single code path to handle operations on that
-- 
2.36.1



[PATCH 2/3] iosys-map: Add per-word write

2022-06-10 Thread Lucas De Marchi
Like was done for read, provide the equivalent for write. Even if
current users are not in the hot path, this should future-proof it.

Signed-off-by: Lucas De Marchi 
---
 include/linux/iosys-map.h | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index cd28c7a1b79c..793e5cd50dbf 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -336,8 +336,11 @@ static inline void iosys_map_memset(struct iosys_map *dst, 
size_t offset,
 #ifdef CONFIG_64BIT
 #define __iosys_map_rd_io_u64_case(val_, vaddr_iomem_) \
u64: val_ = readq(vaddr_iomem_),
+#define __iosys_map_wr_io_u64_case(val_, vaddr_iomem_) \
+   u64: writeq(val_, vaddr_iomem_),
 #else
 #define __iosys_map_rd_io_u64_case(val_, vaddr_iomem_)
+#define __iosys_map_wr_io_u64_case(val_, vaddr_iomem_)
 #endif
 
 #define __iosys_map_rd_io(val__, vaddr_iomem__, type__) _Generic(val__,
\
@@ -347,6 +350,13 @@ static inline void iosys_map_memset(struct iosys_map *dst, 
size_t offset,
__iosys_map_rd_io_u64_case(val__, vaddr_iomem__)\
default: memcpy_fromio(&(val__), vaddr_iomem__, sizeof(val__)))
 
+#define __iosys_map_wr_io(val__, vaddr_iomem__, type__) _Generic(val__,
\
+   u8: writeb(val__, vaddr_iomem__),   \
+   u16: writew(val__, vaddr_iomem__),  \
+   u32: writel(val__, vaddr_iomem__),  \
+   __iosys_map_wr_io_u64_case(val__, vaddr_iomem__)\
+   default: memcpy_toio(vaddr_iomem__, , sizeof(val)))
+
 /**
  * iosys_map_rd - Read a C-type value from the iosys_map
  *
@@ -381,9 +391,13 @@ static inline void iosys_map_memset(struct iosys_map *dst, 
size_t offset,
  * Write a C-type value to the iosys_map, handling possible un-aligned accesses
  * to the mapping.
  */
-#define iosys_map_wr(map__, offset__, type__, val__) ({
\
-   type__ val = (val__);   \
-   iosys_map_memcpy_to(map__, offset__, , sizeof(val));\
+#define iosys_map_wr(map__, offset__, type__, val__) ({
\
+   type__ val = (val__);   
\
+   if ((map__)->is_iomem) {
\
+   __iosys_map_wr_io(val, (map__)->vaddr_iomem + offset__, 
type__);\
+   } else {
\
+   memcpy((map__)->vaddr + offset__, , sizeof(val));   
\
+   }   
\
 })
 
 /**
-- 
2.36.1



Re: [PATCH] drm/msm/mdp4: Fix refcount leak in mdp4_modeset_init_intf

2022-06-10 Thread Abhinav Kumar




On 6/7/2022 4:08 AM, Miaoqian Lin wrote:

of_graph_get_remote_node() returns remote device node pointer with
refcount incremented, we should use of_node_put() on it
when not need anymore.
Add missing of_node_put() to avoid refcount leak.

Fixes: 86418f90a4c1 ("drm: convert drivers to use of_graph_get_remote_node")
Signed-off-by: Miaoqian Lin 
---
  drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 2 ++
  1 file changed, 2 insertions(+)



This patch itself looks fine and will cover the cases when there was an 
error and we did not release the refcount.


But, even in the normal cases I am not finding where we are releasing 
the refcount for the panel_node.


I dont see a of_node_put() on mdp4_lcdc_encoder->panel_node.

Am i missing something?


diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c 
b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
index fb48c8c19ec3..17cb1fc78379 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
@@ -216,6 +216,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,
encoder = mdp4_lcdc_encoder_init(dev, panel_node);
if (IS_ERR(encoder)) {
DRM_DEV_ERROR(dev->dev, "failed to construct LCDC 
encoder\n");
+   of_node_put(panel_node);
return PTR_ERR(encoder);
}
  
@@ -225,6 +226,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,

connector = mdp4_lvds_connector_init(dev, panel_node, encoder);
if (IS_ERR(connector)) {
DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS 
connector\n");
+   of_node_put(panel_node);
return PTR_ERR(connector);
}
  


[PATCH 1/2] drm/msm/mdp5: Add perf data for MDP v1.16

2022-06-10 Thread Luca Weiss
From: Vladimir Lypak 

Add the perf data for the mdp found in msm8953.

Signed-off-by: Vladimir Lypak 
Signed-off-by: Luca Weiss 
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
index 1bf9ff5dbabc..b17f868ffca8 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
@@ -837,6 +837,11 @@ static const struct mdp5_cfg_hw msm8x53_config = {
[2] = INTF_DSI,
},
},
+   .perf = {
+   .ab_inefficiency = 100,
+   .ib_inefficiency = 200,
+   .clk_inefficiency = 105
+   },
.max_clk = 4,
 };
 
-- 
2.36.1



Re: [Freedreno] [PATCH] drm/msm: less magic numbers in msm_mdss_enable

2022-06-10 Thread Abhinav Kumar




On 6/8/2022 11:08 PM, Dmitry Baryshkov wrote:

On Thu, 9 Jun 2022 at 02:37, Abhinav Kumar  wrote:




On 6/8/2022 3:46 PM, Dmitry Baryshkov wrote:

On 09/06/2022 01:42, Abhinav Kumar wrote:



On 6/8/2022 3:38 PM, Dmitry Baryshkov wrote:

On 09/06/2022 01:35, Abhinav Kumar wrote:



On 6/8/2022 3:30 PM, Dmitry Baryshkov wrote:

On Wed, 8 Jun 2022 at 22:29, Abhinav Kumar
 wrote:




On 6/2/2022 1:13 PM, Dmitry Baryshkov wrote:

On Thu, 2 Jun 2022 at 21:18, Abhinav Kumar
 wrote:




On 6/1/2022 1:04 PM, Dmitry Baryshkov wrote:

On Wed, 1 Jun 2022 at 20:38, Abhinav Kumar
 wrote:




On 6/1/2022 2:46 AM, Dmitry Baryshkov wrote:

On Wed, 1 Jun 2022 at 01:01, Abhinav Kumar
 wrote:

On 5/31/2022 5:18 AM, Dmitry Baryshkov wrote:

Replace magic register writes in msm_mdss_enable() with
version that
contains less magic and more variable names that can be
traced back to
the dpu_hw_catalog or the downstream dtsi files.

Signed-off-by: Dmitry Baryshkov 
---
   drivers/gpu/drm/msm/msm_mdss.c | 79
++
   1 file changed, 71 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_mdss.c
b/drivers/gpu/drm/msm/msm_mdss.c
index 0454a571adf7..2a48263cd1b5 100644
--- a/drivers/gpu/drm/msm/msm_mdss.c
+++ b/drivers/gpu/drm/msm/msm_mdss.c
@@ -21,6 +21,7 @@
   #define HW_REV  0x0
   #define HW_INTR_STATUS  0x0010

+#define UBWC_DEC_HW_VERSION  0x58
   #define UBWC_STATIC 0x144
   #define UBWC_CTRL_2 0x150
   #define UBWC_PREDICTION_MODE0x154
@@ -132,9 +133,63 @@ static int
_msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss)
   return 0;
   }

+#define UBWC_1_0 0x1000
+#define UBWC_2_0 0x2000
+#define UBWC_3_0 0x3000
+#define UBWC_4_0 0x4000
+
+static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss
*msm_mdss,
+u32 ubwc_static)
+{
+ writel_relaxed(ubwc_static, msm_mdss->mmio +
UBWC_STATIC);
+}
+
+static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss
*msm_mdss,
+unsigned int
ubwc_version,
+u32 ubwc_swizzle,
+u32 highest_bank_bit,
+u32 macrotile_mode)
+{
+ u32 value = (ubwc_swizzle & 0x1) |
+ (highest_bank_bit & 0x3) << 4 |
+ (macrotile_mode & 0x1) << 12;
+
+ if (ubwc_version == UBWC_3_0)
+ value |= BIT(10);
+
+ if (ubwc_version == UBWC_1_0)
+ value |= BIT(8);
+
+ writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC);
+}
+
+static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss
*msm_mdss,
+unsigned int
ubwc_version,
+u32 ubwc_swizzle,
+u32 ubwc_static,
+u32 highest_bank_bit,
+u32 macrotile_mode)
+{
+ u32 value = (ubwc_swizzle & 0x7) |
+ (ubwc_static & 0x1) << 3 |
+ (highest_bank_bit & 0x7) << 4 |
+ (macrotile_mode & 0x1) << 12;
+
+ writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC);
+
+ if (ubwc_version == UBWC_3_0) {
+ writel_relaxed(1, msm_mdss->mmio + UBWC_CTRL_2);
+ writel_relaxed(0, msm_mdss->mmio +
UBWC_PREDICTION_MODE);
+ } else {
+ writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2);
+ writel_relaxed(1, msm_mdss->mmio +
UBWC_PREDICTION_MODE);
+ }
+}
+


Is it possible to unify the above functions by having the
internal
ubwc_version checks?


Note, it's not the ubwc_version, it is the
ubwc_dec_hw_version. And
also different functions take different sets of arguments.


It seems like msm_mdss_setup_ubwc_dec_xxx can keep growing.

I have not looked into each bit programming but from the top
level so
feel free to correct if wrong but it seems both do write
UBWC_STATIC
(different values based on different UBWC versions) and
write some extra
registers based on version


This is what both the current code and the downstream do. See
https://github.com/MiCode/Xiaomi_Kernel_OpenSource/blob/zeus-s-oss/techpack/display-drivers/msm/sde/sde_hw_top.c#L312




Thanks for pointing to the downstream method for this,

This is exactly what i was also suggesting to do when I mentioned
unifying the above functions.

So instead of having a separate function for each version why
not handle
all the versions in the same function like what the link you
have shown
does.


I wouldn't like that. The downstream uses hw_catalog to pass all
possible parameters. We do not, so we'd have a whole set of
artificial
values.



Now that you brought that up, why cannot even upstream dpu start
using
catalog for ubwc settings?


Because msm_mdss lives out of disp/dpu1. And using the disp/dpu1 for
it would be an inversion of 

[PATCH] drm/msm/dsi: Use single function for reset

2022-06-10 Thread Luca Weiss
From: Vladimir Lypak 

There is currently two function for performing reset: dsi_sw_reset and
dsi_sw_reset_restore. Only difference betwean those is that latter one
assumes that DSI controller is enabled. In contrary former one assumes
that controller is disabled and executed during power-on. However this
assumtion is not true mobile devices which have boot splash set up by
boot-loader.

This patch removes dsi_sw_reset_restore and makes dsi_sw_reset disable
DSI controller during reset sequence if it's enabled.

Signed-off-by: Vladimir Lypak 
Signed-off-by: Luca Weiss 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 48 +-
 1 file changed, 21 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index a95d5df52653..bab2634ebd11 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1080,12 +1080,32 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
 
 static void dsi_sw_reset(struct msm_dsi_host *msm_host)
 {
+   u32 ctrl;
+
+   ctrl = dsi_read(msm_host, REG_DSI_CTRL);
+
+   if (ctrl & DSI_CTRL_ENABLE) {
+   dsi_write(msm_host, REG_DSI_CTRL, ctrl & ~DSI_CTRL_ENABLE);
+   /*
+* dsi controller need to be disabled before
+* clocks turned on
+*/
+   wmb();
+   }
+
dsi_write(msm_host, REG_DSI_CLK_CTRL, DSI_CLK_CTRL_ENABLE_CLKS);
wmb(); /* clocks need to be enabled before reset */
 
+   /* dsi controller can only be reset while clocks are running */
dsi_write(msm_host, REG_DSI_RESET, 1);
msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */
dsi_write(msm_host, REG_DSI_RESET, 0);
+   wmb(); /* controller out of reset */
+
+   if (ctrl & DSI_CTRL_ENABLE) {
+   dsi_write(msm_host, REG_DSI_CTRL, ctrl);
+   wmb();  /* make sure dsi controller enabled again */
+   }
 }
 
 static void dsi_op_mode_config(struct msm_dsi_host *msm_host,
@@ -1478,32 +1498,6 @@ static int dsi_cmds2buf_tx(struct msm_dsi_host *msm_host,
return len;
 }
 
-static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host)
-{
-   u32 data0, data1;
-
-   data0 = dsi_read(msm_host, REG_DSI_CTRL);
-   data1 = data0;
-   data1 &= ~DSI_CTRL_ENABLE;
-   dsi_write(msm_host, REG_DSI_CTRL, data1);
-   /*
-* dsi controller need to be disabled before
-* clocks turned on
-*/
-   wmb();
-
-   dsi_write(msm_host, REG_DSI_CLK_CTRL, DSI_CLK_CTRL_ENABLE_CLKS);
-   wmb();  /* make sure clocks enabled */
-
-   /* dsi controller can only be reset while clocks are running */
-   dsi_write(msm_host, REG_DSI_RESET, 1);
-   msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */
-   dsi_write(msm_host, REG_DSI_RESET, 0);
-   wmb();  /* controller out of reset */
-   dsi_write(msm_host, REG_DSI_CTRL, data0);
-   wmb();  /* make sure dsi controller enabled again */
-}
-
 static void dsi_hpd_worker(struct work_struct *work)
 {
struct msm_dsi_host *msm_host =
@@ -1520,7 +1514,7 @@ static void dsi_err_worker(struct work_struct *work)
 
pr_err_ratelimited("%s: status=%x\n", __func__, status);
if (status & DSI_ERR_STATE_MDP_FIFO_UNDERFLOW)
-   dsi_sw_reset_restore(msm_host);
+   dsi_sw_reset(msm_host);
 
/* It is safe to clear here because error irq is disabled. */
msm_host->err_work_state = 0;
-- 
2.36.1



Re: drm/vc4: module dysfunctional on Raspberry Pi 3B as of 5.18.0

2022-06-10 Thread Peter Robinson
On Thu, Jun 9, 2022 at 10:33 PM Stefan Wahren  wrote:
>
> Hi Peter,
>
> Am 09.06.22 um 13:52 schrieb Peter Robinson:
> > As of Linux 5.18.0, module vc4 apparently isn't working on Raspberry Pi
> > 3B any more.
> >
> > If a monitor is attached to the device, the boot messages show up as
> > usual, but right when KMS starts, the screen turns black. Similarly, the
> > screen also turns black when the module is blacklisted at boot time and
> > loaded from the running system.
> > The problem looks quite similar to the one posted some months ago in 
> > [1].
> >>> If I understand you properly, it results in a blank screen if the
> >>> monitor is connected, but the system is still responsive?
> >>>
> >>> If so, it's a very different problem than the link you provided, since
> >>> it was occurring when no monitor was connected and resulted in a total
> >>> system hang.
> >>>
> > Unfortunately, looking through systemd's journal didn't seem to yield
> > any real hint. Nevertheless, the results from grepping vc4 are
>  I'm seeing the same issue with vc4 on a RPi3 on 5.18.1 on Fedora so
>  can confirm the regression. Maxime would know what might be up here?
> >> i assume you are using the downstream DTB?
> > In this case it's the one in the Linux kernel (not sure if that's
> > upstream or downstream in this context) not the one provided by the
> > RPi firmware.
>
> okay thanks. I tried the kernel config but its huge.

Welcome to distro configs.

> Is it correct that the issue occurs with your kernel config, but not
> with multi_v7_defconfig?

I've not tried it, ultimately the distro config is where it's used and
the rpi config within that hasn't changed for some time.

> >
> >> Please provide the version/date of the GPU firmware?
> > [6.205121] raspberrypi-firmware soc:firmware: Attached to firmware
> > from 2022-05-24T13:26:52
> > Which is git f145afc
> This is good. I had issues with older firmware which didn't implement
> RPI_FIRMWARE_NOTIFY_DISPLAY_DONE. So it must be something different.


Re: [PATCH] dt-bindings: display: panel-simple: Add Arm virtual platforms display

2022-06-10 Thread Rob Herring
On Fri, Jun 10, 2022 at 2:55 PM Sam Ravnborg  wrote:
>
> Hi Rob,
>
> On Fri, Jun 10, 2022 at 02:38:18PM -0600, Rob Herring wrote:
> > 'arm,rtsm-display' is a panel for Arm, Ltd. virtual platforms (e.g. FVP).
> > The binding has been in use for a long time, but was never documented.
> >
> > Some users and an example have a 'panel-dpi' compatible, but that's not
> > needed without a 'panel-timing' node which none of the users have since
> > commit 928faf5e3e8d ("arm64: dts: fvp: Remove panel timings"). The
> > example does have a 'panel-timing' node, but it should not for the
> > same reasons the node was removed in the dts files. So update the
> > example in arm,pl11x.yaml to match the schema.
> >
> > Cc: Linus Walleij 
> > Cc: Robin Murphy 
> > Cc: Andre Przywara 
> > Signed-off-by: Rob Herring 
> > ---
> >  .../bindings/display/arm,pl11x.yaml   | 15 +-
> >  .../bindings/display/panel/panel-simple.yaml  | 20 +--
> >  2 files changed, 15 insertions(+), 20 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/display/arm,pl11x.yaml 
> > b/Documentation/devicetree/bindings/display/arm,pl11x.yaml
> > index b545c6d20325..6cc9045e5c68 100644
> > --- a/Documentation/devicetree/bindings/display/arm,pl11x.yaml
> > +++ b/Documentation/devicetree/bindings/display/arm,pl11x.yaml
> > @@ -159,25 +159,12 @@ examples:
> >  };
> >
> >  panel {
> > -compatible = "arm,rtsm-display", "panel-dpi";
> > -power-supply = <_supply>;
> > +compatible = "arm,rtsm-display";
> >
> >  port {
> >  clcd_panel: endpoint {
> >  remote-endpoint = <_pads>;
> >  };
> >  };
> > -
> > -panel-timing {
> > -clock-frequency = <25175000>;
> > -hactive = <640>;
> > -hback-porch = <40>;
> > -hfront-porch = <24>;
> > -hsync-len = <96>;
> > -vactive = <480>;
> > -vback-porch = <32>;
> > -vfront-porch = <11>;
> > -vsync-len = <2>;
> > -};
> >  };
> >  ...
> > diff --git 
> > a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml 
> > b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> > index 21ba90c9fe33..97afd276c54a 100644
> > --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> > +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> > @@ -19,9 +19,6 @@ description: |
> >
> >If the panel is more advanced a dedicated binding file is required.
> >
> > -allOf:
> > -  - $ref: panel-common.yaml#
> > -
> >  properties:
> >
> >compatible:
> > @@ -35,6 +32,8 @@ properties:
> >- ampire,am-480272h3tmqw-t01h
> >  # Ampire AM-800480R3TMQW-A1H 7.0" WVGA TFT LCD panel
> >- ampire,am800480r3tmqwa1h
> > +# Arm, Ltd. Virtual Platforms Display
> > +  - arm,rtsm-display
> >  # AU Optronics Corporation 10.1" WSVGA TFT LCD panel
> >- auo,b101aw03
> >  # AU Optronics Corporation 10.1" WSVGA TFT LCD panel
> > @@ -340,9 +339,18 @@ properties:
> >
> >  additionalProperties: false
> >
> > -required:
> > -  - compatible
> > -  - power-supply
> > +allOf:
> > +  - $ref: panel-common.yaml#
> > +  - if:
> > +  # Most 'simple' panels must have a single supply, but a virtual 
> > display does not
> > +  not:
> > +properties:
> > +  compatible:
> > +contains:
> > +  const: arm,rtsm-display
> > +then:
> > +  required:
> > +- power-supply
>
> Sorry, but I do not like this change. The beauty of panel-simple is that
> this is a collection of simple display with identical bindings because
> the HW is more or less the same (in general - not in details like size
> etc).
>
> Any panels that requires more are pushed out to their own binding and
> for arm,rtsm-display that would be better.

But I require less...

> It is not this single exceptions that bothers me, it is the many
> exceptions we will have in a few years from now.

Fair enough, I'll make it a separate file.

Rob


[PATCH] drm/i915/guc/slpc: Add a new SLPC selftest

2022-06-10 Thread Vinay Belgaumkar
This test will validate we can achieve actual frequency of RP0. Pcode
grants frequencies based on what GuC is requesting. However, thermal
throttling can limit what is being granted. Add a test to request for
max, but don't fail the test if RP0 is not granted due to throttle
reasons.

Also optimize the selftest by using a common run_test function to avoid
code duplication. Rename the "clamp" tests to vary_max_freq and vary_min_freq.

Fixes 8ee2c227822e ("drm/i915/guc/slpc: Add SLPC selftest")
Signed-off-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/selftest_slpc.c | 322 
 1 file changed, 157 insertions(+), 165 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c 
b/drivers/gpu/drm/i915/gt/selftest_slpc.c
index b768cea5943d..c361a63530c3 100644
--- a/drivers/gpu/drm/i915/gt/selftest_slpc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c
@@ -8,6 +8,11 @@
 #define delay_for_h2g() usleep_range(H2G_DELAY, H2G_DELAY + 1)
 #define FREQUENCY_REQ_UNIT DIV_ROUND_CLOSEST(GT_FREQUENCY_MULTIPLIER, \
  GEN9_FREQ_SCALER)
+enum test_type {
+   VARY_MIN,
+   VARY_MAX,
+   MAX_GRANTED
+};
 
 static int slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 freq)
 {
@@ -36,147 +41,119 @@ static int slpc_set_max_freq(struct intel_guc_slpc *slpc, 
u32 freq)
return ret;
 }
 
-static int live_slpc_clamp_min(void *arg)
+int vary_max_freq(struct intel_guc_slpc *slpc, struct intel_rps *rps,
+ u32 *max_act_freq)
 {
-   struct drm_i915_private *i915 = arg;
-   struct intel_gt *gt = to_gt(i915);
-   struct intel_guc_slpc *slpc = >uc.guc.slpc;
-   struct intel_rps *rps = >rps;
-   struct intel_engine_cs *engine;
-   enum intel_engine_id id;
-   struct igt_spinner spin;
+   u32 step, max_freq, req_freq;
+   u32 act_freq;
u32 slpc_min_freq, slpc_max_freq;
int err = 0;
 
-   if (!intel_uc_uses_guc_slpc(>uc))
-   return 0;
+   slpc_min_freq = slpc->min_freq;
+   slpc_max_freq = slpc->rp0_freq;
 
-   if (igt_spinner_init(, gt))
-   return -ENOMEM;
+   /* Go from max to min in 5 steps */
+   step = (slpc_max_freq - slpc_min_freq) / NUM_STEPS;
+   *max_act_freq = slpc_min_freq;
+   for (max_freq = slpc_max_freq; max_freq > slpc_min_freq;
+   max_freq -= step) {
+   err = slpc_set_max_freq(slpc, max_freq);
+   if (err)
+   break;
 
-   if (intel_guc_slpc_get_max_freq(slpc, _max_freq)) {
-   pr_err("Could not get SLPC max freq\n");
-   return -EIO;
-   }
+   req_freq = intel_rps_read_punit_req_frequency(rps);
 
-   if (intel_guc_slpc_get_min_freq(slpc, _min_freq)) {
-   pr_err("Could not get SLPC min freq\n");
-   return -EIO;
-   }
+   /* GuC requests freq in multiples of 50/3 MHz */
+   if (req_freq > (max_freq + FREQUENCY_REQ_UNIT)) {
+   pr_err("SWReq is %d, should be at most %d\n", req_freq,
+   max_freq + FREQUENCY_REQ_UNIT);
+   err = -EINVAL;
+   }
 
-   if (slpc_min_freq == slpc_max_freq) {
-   pr_err("Min/Max are fused to the same value\n");
-   return -EINVAL;
+   act_freq =  intel_rps_read_actual_frequency(rps);
+   if (act_freq > *max_act_freq)
+   *max_act_freq = act_freq;
+
+   if (err)
+   break;
}
 
-   intel_gt_pm_wait_for_idle(gt);
-   intel_gt_pm_get(gt);
-   for_each_engine(engine, gt, id) {
-   struct i915_request *rq;
-   u32 step, min_freq, req_freq;
-   u32 act_freq, max_act_freq;
+   return err;
+}
+int vary_min_freq(struct intel_guc_slpc *slpc, struct intel_rps *rps,
+ u32 *max_act_freq)
+{
+   u32 step, min_freq, req_freq;
+   u32 act_freq;
+   u32 slpc_min_freq, slpc_max_freq;
+   int err = 0;
 
-   if (!intel_engine_can_store_dword(engine))
-   continue;
+   slpc_min_freq = slpc->min_freq;
+   slpc_max_freq = slpc->rp0_freq;
 
-   /* Go from min to max in 5 steps */
-   step = (slpc_max_freq - slpc_min_freq) / NUM_STEPS;
-   max_act_freq = slpc_min_freq;
-   for (min_freq = slpc_min_freq; min_freq < slpc_max_freq;
-   min_freq += step) {
-   err = slpc_set_min_freq(slpc, min_freq);
-   if (err)
-   break;
-
-   st_engine_heartbeat_disable(engine);
-
-   rq = igt_spinner_create_request(,
-   engine->kernel_context,
-  

Re: [PATCH v2] drm/msm/dp: check core_initialized before disable interrupts at dp_display_unbind()

2022-06-10 Thread Stephen Boyd
Quoting Kuogee Hsieh (2022-06-06 10:55:39)
> During msm initialize phase, dp_display_unbind() will be called to undo
> initializations had been done by dp_display_bind() previously if there is
> error happen at msm_drm_bind. In this case, core_initialized flag had to
> be check to make sure clocks is on before update DP controller register
> to disable HPD interrupts. Otherwise system will crash due to below NOC
> fatal error.
>
> QTISECLIB [01f01a7ad]CNOC2 ERROR: ERRLOG0_LOW = 0x00061007
> QTISECLIB [01f01a7ad]GEM_NOC ERROR: ERRLOG0_LOW = 0x1007
> QTISECLIB [01f0371a0]CNOC2 ERROR: ERRLOG0_HIGH = 0x0003
> QTISECLIB [01f055297]GEM_NOC ERROR: ERRLOG0_HIGH = 0x0003
> QTISECLIB [01f072beb]CNOC2 ERROR: ERRLOG1_LOW = 0x0024
> QTISECLIB [01f0914b8]GEM_NOC ERROR: ERRLOG1_LOW = 0x0042
> QTISECLIB [01f0ae639]CNOC2 ERROR: ERRLOG1_HIGH = 0x4002
> QTISECLIB [01f0cc73f]GEM_NOC ERROR: ERRLOG1_HIGH = 0x4002
> QTISECLIB [01f0ea092]CNOC2 ERROR: ERRLOG2_LOW = 0x0009020c
> QTISECLIB [01f10895f]GEM_NOC ERROR: ERRLOG2_LOW = 0x0ae9020c
> QTISECLIB [01f125ae1]CNOC2 ERROR: ERRLOG2_HIGH = 0x
> QTISECLIB [01f143be7]GEM_NOC ERROR: ERRLOG2_HIGH = 0x
> QTISECLIB [01f16153a]CNOC2 ERROR: ERRLOG3_LOW = 0x
> QTISECLIB [01f17fe07]GEM_NOC ERROR: ERRLOG3_LOW = 0x
> QTISECLIB [01f19cf89]CNOC2 ERROR: ERRLOG3_HIGH = 0x
> QTISECLIB [01f1bb08e]GEM_NOC ERROR: ERRLOG3_HIGH = 0x
> QTISECLIB [01f1d8a31]CNOC2 ERROR: SBM1 FAULTINSTATUS0_LOW = 0x0002
> QTISECLIB [01f1f72a4]GEM_NOC ERROR: SBM0 FAULTINSTATUS0_LOW = 0x0001
> QTISECLIB [01f21a217]CNOC3 ERROR: ERRLOG0_LOW = 0x0006
> QTISECLIB [01f23dfd3]NOC error fatal

Don't think this pile of lines really helps anyone, but OK.

>
> changes in v2:
> -- drop the first patch (drm/msm: enable msm irq after all initializations 
> are done successfully at msm_drm_init()) since the problem had been fixed by 
> other patch
>
> Fixes: a65c95ff88f2 ("drm/msm/dp: stop event kernel thread when DP unbind")
> Signed-off-by: Kuogee Hsieh 
> ---

Reviewed-by: Stephen Boyd 


Re: [PATCH v4] drm/msm/dp: force link training for display resolution change

2022-06-10 Thread Stephen Boyd
Quoting Kuogee Hsieh (2022-05-27 14:32:13)
> During display resolution changes display have to be disabled first
> followed by display enabling with new resolution. Display disable
> will turn off both pixel clock and main link clock so that main link
> have to be re trained during display enable to have new video stream

s/re/re-/

> flow again. At current implementation, display enable function manually
> kicks up irq_hpd_handle which will read panel link status and start link
> training if link status is not in sync state. However, there is rare
> case that a particular panel links status keep staying in sync for
> some period of time after main link had been shut down previously at
> display disabled. Main link retraining will not be executed by
> irq_hdp_handle() if the link status read from pane shows it is in

s/pane/panel/

> sync state. If this was happen, then video stream of newer display
> resolution will fail to be transmitted to panel due to main link is
> not in sync between host and panel. This patch force main link always
> be retrained during display enable procedure to prevent this rare
> failed case from happening. Also this implementation are more
> efficient than manual kicking off irq_hpd_handle function.

The description makes it sound like the link status is not updated,
sometimes. Isn't that the real issue here? Not that link training needs
to be done again (which it always does apparently), but that disabling
the display doesn't wait for the link to go down. Or disabling the link
is causing some sort of glitch on the sink causing it to report the
status as OK when it really isn't.

>
> Changes in v2:
> -- set force_link_train flag on DP only (is_edp == false)
>
> Changes in v3:
> -- revise commit  text
> -- add Fixes tag
>
> Changes in v4:
> -- revise commit  text
>
> Fixes: 62671d2ef24b ("drm/msm/dp: fixes wrong connection state caused by 
> failure of link train")
> Signed-off-by: Kuogee Hsieh 

> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index c388323..370348d 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -1688,10 +1689,14 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge)
>
> state =  dp_display->hpd_state;
>
> -   if (state == ST_DISPLAY_OFF)
> +   if (state == ST_DISPLAY_OFF) {
> dp_display_host_phy_init(dp_display);
>
> -   dp_display_enable(dp_display, 0);
> +   if (!dp->is_edp)

Does this assume eDP has one resolution? I don't understand why eDP is
special here, especially if eDP has more than one resolution available
it seems like we would want to retrain the link regardless.

> +   force_link_train = true;
> +   }
> +
> +   dp_display_enable(dp_display, force_link_train);
>
> rc = dp_display_post_enable(dp);
> if (rc) {


Re: [PATCH] dt-bindings: display: panel-simple: Add Arm virtual platforms display

2022-06-10 Thread Sam Ravnborg
Hi Rob,

On Fri, Jun 10, 2022 at 02:38:18PM -0600, Rob Herring wrote:
> 'arm,rtsm-display' is a panel for Arm, Ltd. virtual platforms (e.g. FVP).
> The binding has been in use for a long time, but was never documented.
> 
> Some users and an example have a 'panel-dpi' compatible, but that's not
> needed without a 'panel-timing' node which none of the users have since
> commit 928faf5e3e8d ("arm64: dts: fvp: Remove panel timings"). The
> example does have a 'panel-timing' node, but it should not for the
> same reasons the node was removed in the dts files. So update the
> example in arm,pl11x.yaml to match the schema.
> 
> Cc: Linus Walleij 
> Cc: Robin Murphy 
> Cc: Andre Przywara 
> Signed-off-by: Rob Herring 
> ---
>  .../bindings/display/arm,pl11x.yaml   | 15 +-
>  .../bindings/display/panel/panel-simple.yaml  | 20 +--
>  2 files changed, 15 insertions(+), 20 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/arm,pl11x.yaml 
> b/Documentation/devicetree/bindings/display/arm,pl11x.yaml
> index b545c6d20325..6cc9045e5c68 100644
> --- a/Documentation/devicetree/bindings/display/arm,pl11x.yaml
> +++ b/Documentation/devicetree/bindings/display/arm,pl11x.yaml
> @@ -159,25 +159,12 @@ examples:
>  };
>  
>  panel {
> -compatible = "arm,rtsm-display", "panel-dpi";
> -power-supply = <_supply>;
> +compatible = "arm,rtsm-display";
>  
>  port {
>  clcd_panel: endpoint {
>  remote-endpoint = <_pads>;
>  };
>  };
> -
> -panel-timing {
> -clock-frequency = <25175000>;
> -hactive = <640>;
> -hback-porch = <40>;
> -hfront-porch = <24>;
> -hsync-len = <96>;
> -vactive = <480>;
> -vback-porch = <32>;
> -vfront-porch = <11>;
> -vsync-len = <2>;
> -};
>  };
>  ...
> diff --git 
> a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml 
> b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> index 21ba90c9fe33..97afd276c54a 100644
> --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> @@ -19,9 +19,6 @@ description: |
>  
>If the panel is more advanced a dedicated binding file is required.
>  
> -allOf:
> -  - $ref: panel-common.yaml#
> -
>  properties:
>  
>compatible:
> @@ -35,6 +32,8 @@ properties:
>- ampire,am-480272h3tmqw-t01h
>  # Ampire AM-800480R3TMQW-A1H 7.0" WVGA TFT LCD panel
>- ampire,am800480r3tmqwa1h
> +# Arm, Ltd. Virtual Platforms Display
> +  - arm,rtsm-display
>  # AU Optronics Corporation 10.1" WSVGA TFT LCD panel
>- auo,b101aw03
>  # AU Optronics Corporation 10.1" WSVGA TFT LCD panel
> @@ -340,9 +339,18 @@ properties:
>  
>  additionalProperties: false
>  
> -required:
> -  - compatible
> -  - power-supply
> +allOf:
> +  - $ref: panel-common.yaml#
> +  - if:
> +  # Most 'simple' panels must have a single supply, but a virtual 
> display does not
> +  not:
> +properties:
> +  compatible:
> +contains:
> +  const: arm,rtsm-display
> +then:
> +  required:
> +- power-supply

Sorry, but I do not like this change. The beauty of panel-simple is that
this is a collection of simple display with identical bindings because
the HW is more or less the same (in general - not in details like size
etc).

Any panels that requires more are pushed out to their own binding and
for arm,rtsm-display that would be better.

It is not this single exceptions that bothers me, it is the many
exceptions we will have in a few years from now.

Sam


Re: [PATCH] staging: ftbft: Use backlight helper

2022-06-10 Thread Sam Ravnborg
On Fri, Jun 10, 2022 at 10:43:06PM +0200, Stephen Kitt wrote:
> Hi Sam,
> 
> On Fri, 10 Jun 2022 22:22:59 +0200, Sam Ravnborg  wrote:
> > On Tue, Jun 07, 2022 at 08:55:16PM +0200, Stephen Kitt wrote:
> > > backlight_properties.fb_blank is deprecated. The states it represents
> > > are handled by other properties; but instead of accessing those
> > > properties directly, drivers should use the helpers provided by
> > > backlight.h.
> > > 
> > > Instead of manually checking the power state in struct
> > > backlight_properties, use backlight_is_blank().
> > > 
> > > Signed-off-by: Stephen Kitt 
> > > Cc: Greg Kroah-Hartman 
> > > Cc: "Noralf Trønnes" 
> > > Cc: Thomas Zimmermann 
> > > Cc: Andy Shevchenko 
> > > Cc: Javier Martinez Canillas 
> > > Cc: Len Baker 
> > > Cc: dri-devel@lists.freedesktop.org
> > > Cc: linux-fb...@vger.kernel.org
> > > Cc: linux-stag...@lists.linux.dev
> > > ---
> > >  drivers/staging/fbtft/fb_ssd1351.c | 3 +--
> > >  drivers/staging/fbtft/fbtft-core.c | 3 +--
> > >  2 files changed, 2 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/staging/fbtft/fb_ssd1351.c
> > > b/drivers/staging/fbtft/fb_ssd1351.c index 6fd549a424d5..b8d55aa8c5c7
> > > 100644 --- a/drivers/staging/fbtft/fb_ssd1351.c
> > > +++ b/drivers/staging/fbtft/fb_ssd1351.c
> > > @@ -196,8 +196,7 @@ static int update_onboard_backlight(struct
> > > backlight_device *bd) "%s: power=%d, fb_blank=%d\n",
> > > __func__, bd->props.power, bd->props.fb_blank);  
> > Could you try to kill this use of props.fb_blank too?  ^^
> > A local variable should do the trick.
> 
> I have a pending patch changing this to show props.state instead, that way
> the debug info shows all the backlight-relevant information from props. How
> does that sound?
In the end we want to have only _one_ state for backlight, so the
simpler solution that just use one of the helpers would be better.
For this driver there is no reason to do much anyway.

Sam


Re: [PATCH v3 06/14] drm/msm/hdmi: drop unused GPIO support

2022-06-10 Thread Dmitry Baryshkov

On 10/06/2022 23:46, Stephen Boyd wrote:

Quoting Dmitry Baryshkov (2022-06-09 05:23:42)

The HDMI driver has code to configure extra GPIOs, which predates
pinctrl support. Nowadays all platforms should use pinctrl instead.
Neither of upstreamed Qualcomm platforms uses these properties, so it's
safe to drop them.

Reported-by: kernel test robot 
Signed-off-by: Dmitry Baryshkov 
---


One question

Reviewed-by: Stephen Boyd 


diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 7267167d5ef1..6d79f1b910a5 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -233,6 +233,20 @@ static struct hdmi *msm_hdmi_init(struct platform_device 
*pdev)
 hdmi->pwr_clks[i] = clk;
 }

+   hdmi->hpd_gpiod = devm_gpiod_get_optional(>dev, "hpd", GPIOD_IN);
+   /* This will catch e.g. -EPROBE_DEFER */
+   if (IS_ERR(hdmi->hpd_gpiod)) {
+   ret = PTR_ERR(hdmi->hpd_gpiod);
+   DRM_DEV_ERROR(>dev, "failed to get hpd gpio: (%d)\n", 
ret);


Did you want to print an error with eprobe defer in it?


True. We should use dev_err_probe here. I'll fix it in the next revision.




+   goto fail;
+   }
+
+   if (!hdmi->hpd_gpiod)
+   DBG("failed to get HPD gpio");
+
+   if (hdmi->hpd_gpiod)
+   gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD");
+
 pm_runtime_enable(>dev);

 hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);



--
With best wishes
Dmitry


Re: [PATCH v3 06/14] drm/msm/hdmi: drop unused GPIO support

2022-06-10 Thread Stephen Boyd
Quoting Dmitry Baryshkov (2022-06-09 05:23:42)
> The HDMI driver has code to configure extra GPIOs, which predates
> pinctrl support. Nowadays all platforms should use pinctrl instead.
> Neither of upstreamed Qualcomm platforms uses these properties, so it's
> safe to drop them.
>
> Reported-by: kernel test robot 
> Signed-off-by: Dmitry Baryshkov 
> ---

One question

Reviewed-by: Stephen Boyd 

> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
> index 7267167d5ef1..6d79f1b910a5 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
> @@ -233,6 +233,20 @@ static struct hdmi *msm_hdmi_init(struct platform_device 
> *pdev)
> hdmi->pwr_clks[i] = clk;
> }
>
> +   hdmi->hpd_gpiod = devm_gpiod_get_optional(>dev, "hpd", 
> GPIOD_IN);
> +   /* This will catch e.g. -EPROBE_DEFER */
> +   if (IS_ERR(hdmi->hpd_gpiod)) {
> +   ret = PTR_ERR(hdmi->hpd_gpiod);
> +   DRM_DEV_ERROR(>dev, "failed to get hpd gpio: (%d)\n", 
> ret);

Did you want to print an error with eprobe defer in it?

> +   goto fail;
> +   }
> +
> +   if (!hdmi->hpd_gpiod)
> +   DBG("failed to get HPD gpio");
> +
> +   if (hdmi->hpd_gpiod)
> +   gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD");
> +
> pm_runtime_enable(>dev);
>
> hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);


Re: [PATCH] staging: ftbft: Use backlight helper

2022-06-10 Thread Stephen Kitt
Hi Sam,

On Fri, 10 Jun 2022 22:22:59 +0200, Sam Ravnborg  wrote:
> On Tue, Jun 07, 2022 at 08:55:16PM +0200, Stephen Kitt wrote:
> > backlight_properties.fb_blank is deprecated. The states it represents
> > are handled by other properties; but instead of accessing those
> > properties directly, drivers should use the helpers provided by
> > backlight.h.
> > 
> > Instead of manually checking the power state in struct
> > backlight_properties, use backlight_is_blank().
> > 
> > Signed-off-by: Stephen Kitt 
> > Cc: Greg Kroah-Hartman 
> > Cc: "Noralf Trønnes" 
> > Cc: Thomas Zimmermann 
> > Cc: Andy Shevchenko 
> > Cc: Javier Martinez Canillas 
> > Cc: Len Baker 
> > Cc: dri-devel@lists.freedesktop.org
> > Cc: linux-fb...@vger.kernel.org
> > Cc: linux-stag...@lists.linux.dev
> > ---
> >  drivers/staging/fbtft/fb_ssd1351.c | 3 +--
> >  drivers/staging/fbtft/fbtft-core.c | 3 +--
> >  2 files changed, 2 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/staging/fbtft/fb_ssd1351.c
> > b/drivers/staging/fbtft/fb_ssd1351.c index 6fd549a424d5..b8d55aa8c5c7
> > 100644 --- a/drivers/staging/fbtft/fb_ssd1351.c
> > +++ b/drivers/staging/fbtft/fb_ssd1351.c
> > @@ -196,8 +196,7 @@ static int update_onboard_backlight(struct
> > backlight_device *bd) "%s: power=%d, fb_blank=%d\n",
> >   __func__, bd->props.power, bd->props.fb_blank);  
> Could you try to kill this use of props.fb_blank too?  ^^
> A local variable should do the trick.

I have a pending patch changing this to show props.state instead, that way
the debug info shows all the backlight-relevant information from props. How
does that sound?

Regards,

Stephen


pgpGCbb916E_W.pgp
Description: OpenPGP digital signature


Re: [PATCH] drm/msm/hdmi: fill the pwr_regs bulk regulators

2022-06-10 Thread Stephen Boyd
Quoting Dmitry Baryshkov (2022-06-09 04:31:48)
> Conversion to use bulk regulator API omitted filling the pwr_regs with
> proper regulator IDs. This was left unnoticed, since none of my testing
> platforms has used the pwr_regs. Fix this by propagating regulator ids
> properly.
>
> Fixes: 31b3b1f5e352 ("drm/msm/hdmi: use bulk regulator API")
> Signed-off-by: Dmitry Baryshkov 
> ---

Reviewed-by: Stephen Boyd 


[PATCH] dt-bindings: display: panel-simple: Add Arm virtual platforms display

2022-06-10 Thread Rob Herring
'arm,rtsm-display' is a panel for Arm, Ltd. virtual platforms (e.g. FVP).
The binding has been in use for a long time, but was never documented.

Some users and an example have a 'panel-dpi' compatible, but that's not
needed without a 'panel-timing' node which none of the users have since
commit 928faf5e3e8d ("arm64: dts: fvp: Remove panel timings"). The
example does have a 'panel-timing' node, but it should not for the
same reasons the node was removed in the dts files. So update the
example in arm,pl11x.yaml to match the schema.

Cc: Linus Walleij 
Cc: Robin Murphy 
Cc: Andre Przywara 
Signed-off-by: Rob Herring 
---
 .../bindings/display/arm,pl11x.yaml   | 15 +-
 .../bindings/display/panel/panel-simple.yaml  | 20 +--
 2 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/arm,pl11x.yaml 
b/Documentation/devicetree/bindings/display/arm,pl11x.yaml
index b545c6d20325..6cc9045e5c68 100644
--- a/Documentation/devicetree/bindings/display/arm,pl11x.yaml
+++ b/Documentation/devicetree/bindings/display/arm,pl11x.yaml
@@ -159,25 +159,12 @@ examples:
 };
 
 panel {
-compatible = "arm,rtsm-display", "panel-dpi";
-power-supply = <_supply>;
+compatible = "arm,rtsm-display";
 
 port {
 clcd_panel: endpoint {
 remote-endpoint = <_pads>;
 };
 };
-
-panel-timing {
-clock-frequency = <25175000>;
-hactive = <640>;
-hback-porch = <40>;
-hfront-porch = <24>;
-hsync-len = <96>;
-vactive = <480>;
-vback-porch = <32>;
-vfront-porch = <11>;
-vsync-len = <2>;
-};
 };
 ...
diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml 
b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 21ba90c9fe33..97afd276c54a 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -19,9 +19,6 @@ description: |
 
   If the panel is more advanced a dedicated binding file is required.
 
-allOf:
-  - $ref: panel-common.yaml#
-
 properties:
 
   compatible:
@@ -35,6 +32,8 @@ properties:
   - ampire,am-480272h3tmqw-t01h
 # Ampire AM-800480R3TMQW-A1H 7.0" WVGA TFT LCD panel
   - ampire,am800480r3tmqwa1h
+# Arm, Ltd. Virtual Platforms Display
+  - arm,rtsm-display
 # AU Optronics Corporation 10.1" WSVGA TFT LCD panel
   - auo,b101aw03
 # AU Optronics Corporation 10.1" WSVGA TFT LCD panel
@@ -340,9 +339,18 @@ properties:
 
 additionalProperties: false
 
-required:
-  - compatible
-  - power-supply
+allOf:
+  - $ref: panel-common.yaml#
+  - if:
+  # Most 'simple' panels must have a single supply, but a virtual display 
does not
+  not:
+properties:
+  compatible:
+contains:
+  const: arm,rtsm-display
+then:
+  required:
+- power-supply
 
 examples:
   - |
-- 
2.34.1



Re: [PATCH 2/3] drm/panel: panel-dsi-cm: Use backlight helpers

2022-06-10 Thread Stephen Kitt
On Fri, 10 Jun 2022 21:52:36 +0200, Stephen Kitt  wrote:

> On Fri, 10 Jun 2022 21:28:32 +0200, Sam Ravnborg  wrote:
> > Hi Stephen.
> > On Fri, Jun 10, 2022 at 07:47:20PM +0200, Stephen Kitt wrote:  
> > > Hi Sebastian,
> > > 
> > > On Thu, 9 Jun 2022 23:52:36 +0200, Sebastian Reichel
> > >  wrote:
> > > > On Tue, Jun 07, 2022 at 08:20:25PM +0200, Stephen Kitt wrote:
> > > > > diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c
> > > > > b/drivers/gpu/drm/panel/panel-dsi-cm.c index
> > > > > b58cb064975f..aa36dc6cedd3 100644 ---
> > > > > a/drivers/gpu/drm/panel/panel-dsi-cm.c +++
> > > > > b/drivers/gpu/drm/panel/panel-dsi-cm.c @@ -86,16 +86,10 @@ static
> > > > > void dsicm_bl_power(struct panel_drv_data *ddata, bool enable)
> > > > > return; 
> > > > >   if (enable) {
> > > > > - backlight->props.fb_blank = FB_BLANK_UNBLANK;
> > > > > - backlight->props.state = ~(BL_CORE_FBBLANK |
> > > > > BL_CORE_SUSPENDED);
> > > > > - backlight->props.power = FB_BLANK_UNBLANK;
> > > > > + backlight_enable(backlight);
> > > > >   } else {
> > > > > - backlight->props.fb_blank = FB_BLANK_NORMAL;
> > > > > - backlight->props.power = FB_BLANK_POWERDOWN;
> > > > > - backlight->props.state |= BL_CORE_FBBLANK |
> > > > > BL_CORE_SUSPENDED;
> > > > > + backlight_disable(backlight);
> > > > >   }  
> > > > 
> > > > The brackets can be removed now. Otherwise:
> > > 
> > > > 
> > > > Reviewed-by: Sebastian Reichel 
> > > 
> > > Thanks, I’ll wait a little more to see if there are any other reviews of
> > > the patches and then push a v2 with that fix.
> > It would be very nice if you could kill all uses of FB_BLANK in the
> > drivers/gpu/drm/panel/* drivers, and post them as one series.
> > This is long overdue to introduce the backlight helpers.
> > 
> > The three you posted is already a nice step forward, and there may be
> > more panel drivers I have missed.  
> 
> With this series on top of 5.19-rc1, the only remaining .fb_blank reference
> is in acx565akm_backlight_init() in panel-sony-acx565akm.c; I was planning
> on nuking that along with the other .fb_blank initialisers in a series
> removing .fb_blank entirely from backlight_properties. I’ll add it as a
> fourth patch for drm/panel if that makes things easier!

That’s in drivers/gpu/drm/panel of course, there are a few others elsewhere
(I’ve got patches in flight for most of them, I’ve got the rest ready for
submission).

> There will still be references to FB_BLANK constants since they’re used for
> backlight_properties.power values. Would it make sense to rename those?

Just to make sure — I’m cleaning up backlight_properties.fb_blank, not
fb_ops.fb_blank. I wasn’t planning on touching the latter...

Regards,

Stephen


pgp_E4K9KxWEo.pgp
Description: OpenPGP digital signature


DRM/KMS PWL API Thoughts and Questions

2022-06-10 Thread Harry Wentland
(I'm sending this as an email as lowest common denominator but feel an issue on 
the color-and-hdr repo would be a better interface for productive discussion. 
Please pop over to https://gitlab.freedesktop.org/pq/color-and-hdr/-/issues/10 
if you agree. Hopefully we can drive the discussion there but if there is a 
strong preference for email that works as well. :) )

I've wanted to start a thread to discuss the use of PWL APIs that were 
introduced by Uma a year ago and for which Bhanuprakash provided IGT tests. I 
have come to like the API but as we're getting closer to a real-world use of it 
I have a few questions and comments. As with a lot of complex APIs the devil is 
in the details. Some of those details are currently underspecified, or 
underdocumented and it's important that we all interpret the API the same way.

**The API**

The original patches posted by Uma:
https://patchwork.freedesktop.org/series/90822/
https://patchwork.freedesktop.org/series/90826/

The IGT tests for PWL API:
https://patchwork.freedesktop.org/series/96895/

I've rebased the kernel patches on a slightly more recent kernel, along with an 
AMD implementation:
https://gitlab.freedesktop.org/hwentland/linux/-/tree/color-and-hdr

I've also rebased them on an IGT tree, but that's not too up-to-date:
https://gitlab.freedesktop.org/hwentland/igt-gpu-tools/-/tree/color-and-hdr


**Why do I like the API?**

In order to allow HW composition of HDR planes in linear space we need the 
ability to program at least a per-CRTC regamma (inv_EOTF) to go from linear to 
wire format post-blending. Since userspace might want to apply corrections on 
top of a simple transfer function (such as PQ, BT.709, etc.) it would like a 
way to set a custom LUT.

The existing CRTC gamma LUT defines equally spaced entries. As Pekka shows in 
[1] equally-spaced LUTs have unacceptable error for regamma/inv_EOTF. Hence we 
need finer granularity of our entries near zero while coarse granularity works 
fine toward the brighter values.

[1] https://gitlab.freedesktop.org/pq/color-and-hdr/-/merge_requests/9

HW (at least AMD and Intel HW) implements this ability as segmented piece-wise 
linear LUTs. These define segments of equally spaced entries. These segments 
are constrained by the HW implementation. I like how the PWL API allows 
different drivers to specify the constraints imposed by different HW while 
allowing userspace a generic way of parsing the PWL. This also avoids complex 
calculations in the kernel driver, which might be required for other APIs one 
could envision. If anyone likes I can elaborate on some ideas for an alternate 
API, though all of them will require non-trivial transformations by the kernel 
driver in order to program them to HW.


**Nitpicks**

The API defines everything inside the segments, including flags and values that 
apply to the entire PWL, such as DRM_MODE_LUT_GAMMA, 
DRM_MODE_LUT_REFLECT_NEGATIVE, input_bpc, and output_bpc. If these don't stay 
constant for segments it might complicate the interpretation of segments. I 
suggest we consider these as effectively applying to the entire PWL. We could 
encode them in an overall drm_color_lut struct that includes an array of 
drm_color_lut_range but that's probably not necessary, hence why I called this 
out as a nitpick. I would just like us to be aware of this ambiguity and 
document that these values applies to the entire PWL.


**How to read the PWL**

Let me first give a summary for how this LUT is used in userspace. If you're 
familiar with this please review and comment if I got things wrong. As I 
mentioned, a lot of this is underspecified at the moment so you're reading my 
interpretation.

You can see this behavior in plane_degamma_test [2] in the kms_color.c IGT test 
suite. I suggest the plane_degamma_test here here instead of the 
test_pipe_gamma test as the latter still has Intelisms (assumptions around 
Intel driver/HW behavior) and will not work for other drivers.

Iterate over all enums in PLANE_DEGAMMA_MODE and find a suitable one. How do we 
find the suitable one? More on that below.

Once we have the right PLANE_DEGAMMA_MODE we read the blob for the blob ID 
associated with the PLANE_DEGAMMA_MODE enum. We interpret the blob as an array 
of drm_color_lut_range. See get_segment_data [3].

We can think of our LUT/PWL as f(x) = y. For a traditional equally spaced LUT 
with 1024 entries x would be 0, 1, 2, ..., 1023. For a PWL LUT we need to parse 
the segment data provided in drm_color_lut_range.

Let's look at the 2nd-last entry of the nonlinear_pwl definition for the AMD 
driver [4] (I've correct it here and dropped the DRM_MODE_LUT_REUSE_LAST but 
it's still incorrect in the link) and simplify it to 4 entries for sake of 
readability:

{
.flags = (DRM_MODE_LUT_GAMMA | DRM_MODE_LUT_REFLECT_NEGATIVE | 
DRM_MODE_LUT_INTERPOLATE | DRM_MODE_LUT_NON_DECREASING),
.count = 4,
.input_bpc = 13, .output_bpc = 18,
.start = 1 << 12, .end = 

Re: [PATCH 1/7] fbdev: aty128fb: Use backlight helper

2022-06-10 Thread Sam Ravnborg
Hi Stepehen,

On Tue, Jun 07, 2022 at 09:23:29PM +0200, Stephen Kitt wrote:
> Instead of retrieving the backlight brightness in struct
> backlight_properties manually, and then checking whether the backlight
> should be on at all, use backlight_get_brightness() which does all
> this and insulates this from future changes.
> 
> Signed-off-by: Stephen Kitt 
> Cc: Paul Mackerras 
> Cc: Helge Deller 
> Cc: linux-fb...@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org

This and the other 6 patches in this series are all:
Reviewed-by: Sam Ravnborg 

I did not receive the cover letter, which is why I reply to this mail.

Sam


Re: [PATCH 2/3] drm/panel: panel-dsi-cm: Use backlight helpers

2022-06-10 Thread Stephen Kitt
On Fri, 10 Jun 2022 21:28:32 +0200, Sam Ravnborg  wrote:
> Hi Stephen.
> On Fri, Jun 10, 2022 at 07:47:20PM +0200, Stephen Kitt wrote:
> > Hi Sebastian,
> > 
> > On Thu, 9 Jun 2022 23:52:36 +0200, Sebastian Reichel
> >  wrote:  
> > > On Tue, Jun 07, 2022 at 08:20:25PM +0200, Stephen Kitt wrote:  
> > > > diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c
> > > > b/drivers/gpu/drm/panel/panel-dsi-cm.c index
> > > > b58cb064975f..aa36dc6cedd3 100644 ---
> > > > a/drivers/gpu/drm/panel/panel-dsi-cm.c +++
> > > > b/drivers/gpu/drm/panel/panel-dsi-cm.c @@ -86,16 +86,10 @@ static
> > > > void dsicm_bl_power(struct panel_drv_data *ddata, bool enable) return;
> > > >  
> > > > if (enable) {
> > > > -   backlight->props.fb_blank = FB_BLANK_UNBLANK;
> > > > -   backlight->props.state = ~(BL_CORE_FBBLANK |
> > > > BL_CORE_SUSPENDED);
> > > > -   backlight->props.power = FB_BLANK_UNBLANK;
> > > > +   backlight_enable(backlight);
> > > > } else {
> > > > -   backlight->props.fb_blank = FB_BLANK_NORMAL;
> > > > -   backlight->props.power = FB_BLANK_POWERDOWN;
> > > > -   backlight->props.state |= BL_CORE_FBBLANK |
> > > > BL_CORE_SUSPENDED;
> > > > +   backlight_disable(backlight);
> > > > }
> > > 
> > > The brackets can be removed now. Otherwise:  
> >   
> > > 
> > > Reviewed-by: Sebastian Reichel   
> > 
> > Thanks, I’ll wait a little more to see if there are any other reviews of
> > the patches and then push a v2 with that fix.  
> It would be very nice if you could kill all uses of FB_BLANK in the
> drivers/gpu/drm/panel/* drivers, and post them as one series.
> This is long overdue to introduce the backlight helpers.
> 
> The three you posted is already a nice step forward, and there may be
> more panel drivers I have missed.

With this series on top of 5.19-rc1, the only remaining .fb_blank reference is
in acx565akm_backlight_init() in panel-sony-acx565akm.c; I was planning on
nuking that along with the other .fb_blank initialisers in a series removing
.fb_blank entirely from backlight_properties. I’ll add it as a fourth patch
for drm/panel if that makes things easier!

There will still be references to FB_BLANK constants since they’re used for
backlight_properties.power values. Would it make sense to rename those?

Regards,

Stephen


pgpEgPit4twqj.pgp
Description: OpenPGP digital signature


Re: [PATCH] staging: ftbft: Use backlight helper

2022-06-10 Thread Sam Ravnborg
Hi Stephen,

On Tue, Jun 07, 2022 at 08:55:16PM +0200, Stephen Kitt wrote:
> backlight_properties.fb_blank is deprecated. The states it represents
> are handled by other properties; but instead of accessing those
> properties directly, drivers should use the helpers provided by
> backlight.h.
> 
> Instead of manually checking the power state in struct
> backlight_properties, use backlight_is_blank().
> 
> Signed-off-by: Stephen Kitt 
> Cc: Greg Kroah-Hartman 
> Cc: "Noralf Trønnes" 
> Cc: Thomas Zimmermann 
> Cc: Andy Shevchenko 
> Cc: Javier Martinez Canillas 
> Cc: Len Baker 
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-fb...@vger.kernel.org
> Cc: linux-stag...@lists.linux.dev
> ---
>  drivers/staging/fbtft/fb_ssd1351.c | 3 +--
>  drivers/staging/fbtft/fbtft-core.c | 3 +--
>  2 files changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/staging/fbtft/fb_ssd1351.c 
> b/drivers/staging/fbtft/fb_ssd1351.c
> index 6fd549a424d5..b8d55aa8c5c7 100644
> --- a/drivers/staging/fbtft/fb_ssd1351.c
> +++ b/drivers/staging/fbtft/fb_ssd1351.c
> @@ -196,8 +196,7 @@ static int update_onboard_backlight(struct 
> backlight_device *bd)
> "%s: power=%d, fb_blank=%d\n",
> __func__, bd->props.power, bd->props.fb_blank);
Could you try to kill this use of props.fb_blank too?  ^^
A local variable should do the trick.

Sam

>  
> - on = (bd->props.power == FB_BLANK_UNBLANK) &&
> -  (bd->props.fb_blank == FB_BLANK_UNBLANK);
> + on = !backlight_is_blank(bd);
>   /* Onboard backlight connected to GPIO0 on SSD1351, GPIO1 unused */
>   write_reg(par, 0xB5, on ? 0x03 : 0x02);
>  
> diff --git a/drivers/staging/fbtft/fbtft-core.c 
> b/drivers/staging/fbtft/fbtft-core.c
> index 60b2278d8b16..9b3eaed80cdd 100644
> --- a/drivers/staging/fbtft/fbtft-core.c
> +++ b/drivers/staging/fbtft/fbtft-core.c
> @@ -137,8 +137,7 @@ static int fbtft_backlight_update_status(struct 
> backlight_device *bd)
> "%s: polarity=%d, power=%d, fb_blank=%d\n",
> __func__, polarity, bd->props.power, bd->props.fb_blank);
>  
> - if ((bd->props.power == FB_BLANK_UNBLANK) &&
> - (bd->props.fb_blank == FB_BLANK_UNBLANK))
> + if (!backlight_is_blank(bd))
>   gpiod_set_value(par->gpio.led[0], polarity);
>   else
>   gpiod_set_value(par->gpio.led[0], !polarity);
> 
> base-commit: f2906aa863381afb0015a9eb7fefad885d4e5a56
> -- 
> 2.30.2


Re: [PATCH v7 8/8] drm: Config orientation property if panel provides it

2022-06-10 Thread Stephen Boyd
Quoting Hsin-Yi Wang (2022-06-09 00:27:23)
> Panel orientation property should be set before drm_dev_register().
> Some drm driver calls drm_dev_register() in .bind(). However, most
> panels sets orientation property relatively late, mostly in .get_modes()
> callback, since this is when they are able to get the connector and
> binds the orientation property to it, though the value should be known
> when the panel is probed.
>
> In drm_bridge_connector_init(), if a bridge is a panel bridge, use it to
> set the connector's panel orientation property.
>
> Suggested-by: Doug Anderson 
> Signed-off-by: Hsin-Yi Wang 
> ---

Reviewed-by: Stephen Boyd 


Re: [PATCH 2/3] drm/panel: panel-dsi-cm: Use backlight helpers

2022-06-10 Thread Sam Ravnborg
Hi Stephen,
> > > > 
> > > > Thanks, I’ll wait a little more to see if there are any other reviews of
> > > > the patches and then push a v2 with that fix.
> > > It would be very nice if you could kill all uses of FB_BLANK in the
> > > drivers/gpu/drm/panel/* drivers, and post them as one series.
> > > This is long overdue to introduce the backlight helpers.
> > > 
> > > The three you posted is already a nice step forward, and there may be
> > > more panel drivers I have missed.  
> > 
> > With this series on top of 5.19-rc1, the only remaining .fb_blank reference
> > is in acx565akm_backlight_init() in panel-sony-acx565akm.c; I was planning
> > on nuking that along with the other .fb_blank initialisers in a series
> > removing .fb_blank entirely from backlight_properties. I’ll add it as a
> > fourth patch for drm/panel if that makes things easier!
> 
> That’s in drivers/gpu/drm/panel of course, there are a few others elsewhere
> (I’ve got patches in flight for most of them, I’ve got the rest ready for
> submission).
> 
> > There will still be references to FB_BLANK constants since they’re used for
> > backlight_properties.power values. Would it make sense to rename those?
> 
> Just to make sure — I’m cleaning up backlight_properties.fb_blank, not
> fb_ops.fb_blank. I wasn’t planning on touching the latter...

Nuking props.fb_blank - that a fine goal - so keep focus there.
We can then later revisit the other clean-up possibilities.

Since you do this tree-wide do not do the mistake and try to cover too
much at the same time, because then you never finish.
So forget my comment for now and keep up the good work on removing
props.fb_blank.

Sam


Re: drm/vc4: module dysfunctional on Raspberry Pi 3B as of 5.18.0

2022-06-10 Thread Stefan Wahren

Hi,

Am 09.06.22 um 23:33 schrieb Stefan Wahren:

Hi Peter,

Am 09.06.22 um 13:52 schrieb Peter Robinson:
As of Linux 5.18.0, module vc4 apparently isn't working on 
Raspberry Pi

3B any more.

If a monitor is attached to the device, the boot messages show up as
usual, but right when KMS starts, the screen turns black. 
Similarly, the
screen also turns black when the module is blacklisted at boot 
time and

loaded from the running system.
The problem looks quite similar to the one posted some months ago 
in [1].

If I understand you properly, it results in a blank screen if the
monitor is connected, but the system is still responsive?

If so, it's a very different problem than the link you provided, since
it was occurring when no monitor was connected and resulted in a total
system hang.

Unfortunately, looking through systemd's journal didn't seem to 
yield

any real hint. Nevertheless, the results from grepping vc4 are

I'm seeing the same issue with vc4 on a RPi3 on 5.18.1 on Fedora so
can confirm the regression. Maxime would know what might be up here?

i assume you are using the downstream DTB?

In this case it's the one in the Linux kernel (not sure if that's
upstream or downstream in this context) not the one provided by the
RPi firmware.


okay thanks. I tried the kernel config but its huge.

Is it correct that the issue occurs with your kernel config, but not 
with multi_v7_defconfig?


FWIW here is what i tried to reproduce the issue:

- enable CONFIG_DRM_VC4_HDMI_CEC
- apply the relevant config.txt options from Peter R.
- update my gcc toolchain to 11.3
- switch compiler optimization from speed to size

But the display always works.

Please tell the size of your bcm2837-rpi-3-b.dtb



Re: [PATCH v7 8/8] drm: Config orientation property if panel provides it

2022-06-10 Thread Doug Anderson
Hi,

On Thu, Jun 9, 2022 at 12:28 AM Hsin-Yi Wang  wrote:
>
> Panel orientation property should be set before drm_dev_register().
> Some drm driver calls drm_dev_register() in .bind(). However, most
> panels sets orientation property relatively late, mostly in .get_modes()
> callback, since this is when they are able to get the connector and
> binds the orientation property to it, though the value should be known
> when the panel is probed.
>
> In drm_bridge_connector_init(), if a bridge is a panel bridge, use it to
> set the connector's panel orientation property.
>
> Suggested-by: Doug Anderson 
> Signed-off-by: Hsin-Yi Wang 
> ---
> v6->v7: remove redundant check and fix config issue.
> ---
>  drivers/gpu/drm/bridge/panel.c | 34 ++
>  drivers/gpu/drm/drm_bridge_connector.c |  8 +-
>  include/drm/drm_bridge.h   | 14 +++
>  3 files changed, 55 insertions(+), 1 deletion(-)

Reviewed-by: Doug Anderson 


[PATCH v4] drm/msm: Avoid unclocked GMU register access in 6xx gpu_busy

2022-06-10 Thread Douglas Anderson
>From testing on sc7180-trogdor devices, reading the GMU registers
needs the GMU clocks to be enabled. Those clocks get turned on in
a6xx_gmu_resume(). Confusingly enough, that function is called as a
result of the runtime_pm of the GPU "struct device", not the GMU
"struct device". Unfortunately the current a6xx_gpu_busy() grabs a
reference to the GMU's "struct device".

The fact that we were grabbing the wrong reference was easily seen to
cause crashes that happen if we change the GPU's pm_runtime usage to
not use autosuspend. It's also believed to cause some long tail GPU
crashes even with autosuspend.

We could look at changing it so that we do pm_runtime_get_if_in_use()
on the GPU's "struct device", but then we run into a different
problem. pm_runtime_get_if_in_use() will return 0 for the GPU's
"struct device" the whole time when we're in the "autosuspend
delay". That is, when we drop the last reference to the GPU but we're
waiting a period before actually suspending then we'll think the GPU
is off. One reason that's bad is that if the GPU didn't actually turn
off then the cycle counter doesn't lose state and that throws off all
of our calculations.

Let's change the code to keep track of the suspend state of
devfreq. msm_devfreq_suspend() is always called before we actually
suspend the GPU and msm_devfreq_resume() after we resume it. This
means we can use the suspended state to know if we're powered or not.

NOTE: one might wonder when exactly our status function is called when
devfreq is supposed to be disabled. The stack crawl I captured was:
  msm_devfreq_get_dev_status
  devfreq_simple_ondemand_func
  devfreq_update_target
  qos_notifier_call
  qos_max_notifier_call
  blocking_notifier_call_chain
  pm_qos_update_target
  freq_qos_apply
  apply_constraint
  __dev_pm_qos_update_request
  dev_pm_qos_update_request
  msm_devfreq_idle_work

Fixes: eadf79286a4b ("drm/msm: Check for powered down HW in the devfreq 
callbacks")
Signed-off-by: Douglas Anderson 
Reviewed-by: Rob Clark 
---

Changes in v4:
- Add a comment that gpu_set_freq() / gpu_busy() assume pm resume

Changes in v3:
- Totally rewrote to not use the pm_runtime functions.
- Moved the code to be common for all adreno GPUs.

Changes in v2:
- Move the set_freq runtime pm grab to the GPU file.
- Use <= for the pm_runtime test, not ==.

 drivers/gpu/drm/msm/adreno/a5xx_gpu.c |  8 --
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 13 -
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 12 +++--
 drivers/gpu/drm/msm/adreno/a6xx_gpu.h |  3 ++-
 drivers/gpu/drm/msm/msm_gpu.h | 11 +++-
 drivers/gpu/drm/msm/msm_gpu_devfreq.c | 39 +--
 6 files changed, 53 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index c424e9a37669..3dcec7acb384 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1666,18 +1666,10 @@ static u64 a5xx_gpu_busy(struct msm_gpu *gpu, unsigned 
long *out_sample_rate)
 {
u64 busy_cycles;
 
-   /* Only read the gpu busy if the hardware is already active */
-   if (pm_runtime_get_if_in_use(>pdev->dev) == 0) {
-   *out_sample_rate = 1;
-   return 0;
-   }
-
busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
*out_sample_rate = clk_get_rate(gpu->core_clk);
 
-   pm_runtime_put(>pdev->dev);
-
return busy_cycles;
 }
 
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 9f76f5b15759..dc715d88ff21 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -102,7 +102,8 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
 }
 
-void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
+void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,
+  bool suspended)
 {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
@@ -127,15 +128,16 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct 
dev_pm_opp *opp)
 
/*
 * This can get called from devfreq while the hardware is idle. Don't
-* bring up the power if it isn't already active
+* bring up the power if it isn't already active. All we're doing here
+* is updating the frequency so that when we come back online we're at
+* the right rate.
 */
-   if (pm_runtime_get_if_in_use(gmu->dev) == 0)
+   if (suspended)
return;
 
if (!gmu->legacy) {
a6xx_hfi_set_freq(gmu, perf_index);
dev_pm_opp_set_opp(>pdev->dev, opp);
-   pm_runtime_put(gmu->dev);
return;
}
 
@@ -159,7 +161,6 @@ void a6xx_gmu_set_freq(struct 

Re: [PATCH v2 08/15] drm/probe-helper: add drm_connector_helper_get_modes()

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:38AM +0300, Jani Nikula wrote:
> Add a helper function to be used as the "default" .get_modes()
> hook. This also works as an example of what the driver .get_modes()
> hooks are supposed to do regarding the new drm_edid_read*() and
> drm_edid_connector_update() calls.
> 
> Signed-off-by: Jani Nikula 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/drm_probe_helper.c | 34 ++
>  include/drm/drm_probe_helper.h |  1 +
>  2 files changed, 35 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> b/drivers/gpu/drm/drm_probe_helper.c
> index a8d26b29bfa0..e6b8f2923aa7 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -1049,3 +1049,37 @@ int drm_connector_helper_get_modes_from_ddc(struct 
> drm_connector *connector)
>   return count;
>  }
>  EXPORT_SYMBOL(drm_connector_helper_get_modes_from_ddc);
> +
> +/**
> + * drm_connector_helper_get_modes - Read EDID and update connector.
> + * @connector: The connector
> + *
> + * Read the EDID using drm_edid_read() (which requires that connector->ddc is
> + * set), and update the connector using the EDID.
> + *
> + * This can be used as the "default" connector helper .get_modes() hook if 
> the
> + * driver does not need any special processing. This is sets the example what
> + * custom .get_modes() hooks should do regarding EDID read and connector 
> update.
> + *
> + * Returns: Number of modes.
> + */
> +int drm_connector_helper_get_modes(struct drm_connector *connector)
> +{
> + const struct drm_edid *drm_edid;
> + int count;
> +
> + drm_edid = drm_edid_read(connector);
> +
> + /*
> +  * Unconditionally update the connector. If the EDID was read
> +  * succesfully, fill in the connector information derived from the
> +  * EDID. Otherwise, if the EDID is NULL, clear the connector
> +  * information.
> +  */
> + count = drm_edid_connector_update(connector, drm_edid);
> +
> + drm_edid_free(drm_edid);
> +
> + return count;
> +}
> +EXPORT_SYMBOL(drm_connector_helper_get_modes);
> diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h
> index c80cab7a53b7..8075e02aa865 100644
> --- a/include/drm/drm_probe_helper.h
> +++ b/include/drm/drm_probe_helper.h
> @@ -27,5 +27,6 @@ void drm_kms_helper_poll_enable(struct drm_device *dev);
>  bool drm_kms_helper_is_poll_worker(void);
>  
>  int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector);
> +int drm_connector_helper_get_modes(struct drm_connector *connector);
>  
>  #endif
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel


Re: [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:35AM +0300, Jani Nikula wrote:
> Add new functions drm_edid_read(), drm_edid_read_ddc(), and
> drm_edid_read_custom() to replace drm_get_edid() and drm_do_get_edid()
> for reading the EDID. The transition is expected to happen over a fairly
> long time.
> 
> Note that the new drm_edid_read*() functions do not do any of the
> connector updates anymore. The reading and parsing will be completely
> separated from each other.
> 
> Add new functions drm_edid_alloc(), drm_edid_dup(), and drm_edid_free()
> for allocating and freeing drm_edid containers.
> 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/drm_edid.c | 245 +
>  include/drm/drm_edid.h |   9 ++
>  2 files changed, 230 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2beaa48301c1..2bdaf1e34a9d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2226,29 +2226,9 @@ static enum edid_block_status edid_block_read(void 
> *block, unsigned int block_nu
>   return status;
>  }
>  
> -/**
> - * drm_do_get_edid - get EDID data using a custom EDID block read function
> - * @connector: connector we're probing
> - * @read_block: EDID block read function
> - * @context: private data passed to the block read function
> - *
> - * When the I2C adapter connected to the DDC bus is hidden behind a device 
> that
> - * exposes a different interface to read EDID blocks this function can be 
> used
> - * to get EDID data using a custom block read function.
> - *
> - * As in the general case the DDC bus is accessible by the kernel at the I2C
> - * level, drivers must make all reasonable efforts to expose it as an I2C
> - * adapter and use drm_get_edid() instead of abusing this function.
> - *
> - * The EDID may be overridden using debugfs override_edid or firmware EDID
> - * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this 
> priority
> - * order. Having either of them bypasses actual EDID reads.
> - *
> - * Return: Pointer to valid EDID or NULL if we couldn't find any.
> - */
> -struct edid *drm_do_get_edid(struct drm_connector *connector,
> -  read_block_fn read_block,
> -  void *context)
> +static struct edid *_drm_do_get_edid(struct drm_connector *connector,
> +  read_block_fn read_block, void *context,
> +  size_t *size)
>  {
>   enum edid_block_status status;
>   int i, invalid_blocks = 0;
> @@ -2315,14 +2295,125 @@ struct edid *drm_do_get_edid(struct drm_connector 
> *connector,
>   }
>  
>  ok:
> + if (size)
> + *size = alloc_size;
> +
>   return edid;
>  
>  fail:
>   kfree(edid);
>   return NULL;
>  }
> +
> +/**
> + * drm_do_get_edid - get EDID data using a custom EDID block read function
> + * @connector: connector we're probing
> + * @read_block: EDID block read function
> + * @context: private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device 
> that
> + * exposes a different interface to read EDID blocks this function can be 
> used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_get_edid() instead of abusing this function.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this 
> priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * Return: Pointer to valid EDID or NULL if we couldn't find any.
> + */
> +struct edid *drm_do_get_edid(struct drm_connector *connector,
> +  read_block_fn read_block,
> +  void *context)
> +{
> + return _drm_do_get_edid(connector, read_block, context, NULL);
> +}
>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>  
> +/* Allocate struct drm_edid container *without* duplicating the edid data */
> +static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
> +{
> + struct drm_edid *drm_edid;
> +
> + if (!edid || !size || size < EDID_LENGTH)
> + return NULL;
> +
> + drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
> + if (drm_edid) {
> + drm_edid->edid = edid;
> + drm_edid->size = size;
> + }
> +
> + return drm_edid;
> +}
> +
> +/**
> + * drm_edid_alloc - Allocate a new drm_edid container
> + * @edid: Pointer to raw EDID data
> + * @size: Size of memory allocated for EDID
> + *
> + * Allocate a new drm_edid container. Do not calculate edid size from edid, 
> pass
> + * the actual size that has been allocated for the data. There is no 
> 

Re: [PATCH v2 07/15] drm/probe-helper: abstract .get_modes() connector helper call

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:37AM +0300, Jani Nikula wrote:
> Abstract the .get_modes() connector helper call, including the
> override/firmware EDID fallback, for clarity.
> 
> Signed-off-by: Jani Nikula 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/drm_probe_helper.c | 29 +++--
>  1 file changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> b/drivers/gpu/drm/drm_probe_helper.c
> index 75a71649b64d..a8d26b29bfa0 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -354,6 +354,24 @@ drm_helper_probe_detect(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_helper_probe_detect);
>  
> +static int drm_helper_probe_get_modes(struct drm_connector *connector)
> +{
> + const struct drm_connector_helper_funcs *connector_funcs =
> + connector->helper_private;
> + int count;
> +
> + count = connector_funcs->get_modes(connector);
> +
> + /*
> +  * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
> +  * override/firmware EDID.
> +  */
> + if (count == 0 && connector->status == connector_status_connected)
> + count = drm_add_override_edid_modes(connector);
> +
> + return count;
> +}
> +
>  static int __drm_helper_update_and_validate(struct drm_connector *connector,
>   uint32_t maxX, uint32_t maxY,
>   struct drm_modeset_acquire_ctx *ctx)
> @@ -473,8 +491,6 @@ int drm_helper_probe_single_connector_modes(struct 
> drm_connector *connector,
>  {
>   struct drm_device *dev = connector->dev;
>   struct drm_display_mode *mode;
> - const struct drm_connector_helper_funcs *connector_funcs =
> - connector->helper_private;
>   int count = 0, ret;
>   enum drm_connector_status old_status;
>   struct drm_modeset_acquire_ctx ctx;
> @@ -559,14 +575,7 @@ int drm_helper_probe_single_connector_modes(struct 
> drm_connector *connector,
>   goto exit;
>   }
>  
> - count = (*connector_funcs->get_modes)(connector);
> -
> - /*
> -  * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
> -  * override/firmware EDID.
> -  */
> - if (count == 0 && connector->status == connector_status_connected)
> - count = drm_add_override_edid_modes(connector);
> + count = drm_helper_probe_get_modes(connector);
>  
>   if (count == 0 && (connector->status == connector_status_connected ||
>  connector->status == connector_status_unknown)) {
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel


Re: [PATCH v2 05/15] drm/edid: add new interfaces around struct drm_edid

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:35AM +0300, Jani Nikula wrote:
> Add new functions drm_edid_read(), drm_edid_read_ddc(), and
> drm_edid_read_custom() to replace drm_get_edid() and drm_do_get_edid()
> for reading the EDID. The transition is expected to happen over a fairly
> long time.
> 
> Note that the new drm_edid_read*() functions do not do any of the
> connector updates anymore. The reading and parsing will be completely
> separated from each other.
> 
> Add new functions drm_edid_alloc(), drm_edid_dup(), and drm_edid_free()
> for allocating and freeing drm_edid containers.
> 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Signed-off-by: Jani Nikula 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/drm_edid.c | 245 +
>  include/drm/drm_edid.h |   9 ++
>  2 files changed, 230 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2beaa48301c1..2bdaf1e34a9d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2226,29 +2226,9 @@ static enum edid_block_status edid_block_read(void 
> *block, unsigned int block_nu
>   return status;
>  }
>  
> -/**
> - * drm_do_get_edid - get EDID data using a custom EDID block read function
> - * @connector: connector we're probing
> - * @read_block: EDID block read function
> - * @context: private data passed to the block read function
> - *
> - * When the I2C adapter connected to the DDC bus is hidden behind a device 
> that
> - * exposes a different interface to read EDID blocks this function can be 
> used
> - * to get EDID data using a custom block read function.
> - *
> - * As in the general case the DDC bus is accessible by the kernel at the I2C
> - * level, drivers must make all reasonable efforts to expose it as an I2C
> - * adapter and use drm_get_edid() instead of abusing this function.
> - *
> - * The EDID may be overridden using debugfs override_edid or firmware EDID
> - * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this 
> priority
> - * order. Having either of them bypasses actual EDID reads.
> - *
> - * Return: Pointer to valid EDID or NULL if we couldn't find any.
> - */
> -struct edid *drm_do_get_edid(struct drm_connector *connector,
> -  read_block_fn read_block,
> -  void *context)
> +static struct edid *_drm_do_get_edid(struct drm_connector *connector,
> +  read_block_fn read_block, void *context,
> +  size_t *size)
>  {
>   enum edid_block_status status;
>   int i, invalid_blocks = 0;
> @@ -2315,14 +2295,125 @@ struct edid *drm_do_get_edid(struct drm_connector 
> *connector,
>   }
>  
>  ok:
> + if (size)
> + *size = alloc_size;
> +
>   return edid;
>  
>  fail:
>   kfree(edid);
>   return NULL;
>  }
> +
> +/**
> + * drm_do_get_edid - get EDID data using a custom EDID block read function
> + * @connector: connector we're probing
> + * @read_block: EDID block read function
> + * @context: private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device 
> that
> + * exposes a different interface to read EDID blocks this function can be 
> used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_get_edid() instead of abusing this function.
> + *
> + * The EDID may be overridden using debugfs override_edid or firmware EDID
> + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this 
> priority
> + * order. Having either of them bypasses actual EDID reads.
> + *
> + * Return: Pointer to valid EDID or NULL if we couldn't find any.
> + */
> +struct edid *drm_do_get_edid(struct drm_connector *connector,
> +  read_block_fn read_block,
> +  void *context)
> +{
> + return _drm_do_get_edid(connector, read_block, context, NULL);
> +}
>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>  
> +/* Allocate struct drm_edid container *without* duplicating the edid data */
> +static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
> +{
> + struct drm_edid *drm_edid;
> +
> + if (!edid || !size || size < EDID_LENGTH)
> + return NULL;
> +
> + drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL);
> + if (drm_edid) {
> + drm_edid->edid = edid;
> + drm_edid->size = size;
> + }
> +
> + return drm_edid;
> +}
> +
> +/**
> + * drm_edid_alloc - Allocate a new drm_edid container
> + * @edid: Pointer to raw EDID data
> + * @size: Size of memory allocated for EDID
> + *
> + * Allocate a new drm_edid container. Do not calculate edid size from edid, 
> pass
> + * the actual size that has been allocated 

Re: [PATCH v2 04/15] drm/edid: keep track of alloc size in drm_do_get_edid()

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:34AM +0300, Jani Nikula wrote:
> We'll want to return the allocated buffer size in the future. Keep track
> of it.
> 
> Signed-off-by: Jani Nikula 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/drm_edid.c | 27 +++
>  1 file changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index f44ada4bfa5b..2beaa48301c1 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2021,13 +2021,16 @@ bool drm_edid_is_valid(struct edid *edid)
>  EXPORT_SYMBOL(drm_edid_is_valid);
>  
>  static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
> -int invalid_blocks)
> +int invalid_blocks,
> +size_t *alloc_size)
>  {
>   struct edid *new, *dest_block;
>   int valid_extensions = edid->extensions - invalid_blocks;
>   int i;
>  
> - new = kmalloc(edid_size_by_blocks(valid_extensions + 1), GFP_KERNEL);
> + *alloc_size = edid_size_by_blocks(valid_extensions + 1);
> +
> + new = kmalloc(*alloc_size, GFP_KERNEL);
>   if (!new)
>   goto out;
>  
> @@ -2140,7 +2143,8 @@ static void connector_bad_edid(struct drm_connector 
> *connector,
>  }
>  
>  /* Get override or firmware EDID */
> -static struct edid *drm_get_override_edid(struct drm_connector *connector)
> +static struct edid *drm_get_override_edid(struct drm_connector *connector,
> +   size_t *alloc_size)
>  {
>   struct edid *override = NULL;
>  
> @@ -2150,6 +2154,10 @@ static struct edid *drm_get_override_edid(struct 
> drm_connector *connector)
>   if (!override)
>   override = drm_load_edid_firmware(connector);
>  
> + /* FIXME: Get alloc size from deeper down the stack */
> + if (!IS_ERR_OR_NULL(override) && alloc_size)
> + *alloc_size = edid_size(override);
> +
>   return IS_ERR(override) ? NULL : override;
>  }
>  
> @@ -2169,7 +2177,7 @@ int drm_add_override_edid_modes(struct drm_connector 
> *connector)
>   struct edid *override;
>   int num_modes = 0;
>  
> - override = drm_get_override_edid(connector);
> + override = drm_get_override_edid(connector, NULL);
>   if (override) {
>   drm_connector_update_edid_property(connector, override);
>   num_modes = drm_add_edid_modes(connector, override);
> @@ -2245,12 +2253,13 @@ struct edid *drm_do_get_edid(struct drm_connector 
> *connector,
>   enum edid_block_status status;
>   int i, invalid_blocks = 0;
>   struct edid *edid, *new;
> + size_t alloc_size = EDID_LENGTH;
>  
> - edid = drm_get_override_edid(connector);
> + edid = drm_get_override_edid(connector, _size);
>   if (edid)
>   goto ok;
>  
> - edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
> + edid = kmalloc(alloc_size, GFP_KERNEL);
>   if (!edid)
>   return NULL;
>  
> @@ -2278,7 +2287,8 @@ struct edid *drm_do_get_edid(struct drm_connector 
> *connector,
>   if (!edid_extension_block_count(edid))
>   goto ok;
>  
> - new = krealloc(edid, edid_size(edid), GFP_KERNEL);
> + alloc_size = edid_size(edid);
> + new = krealloc(edid, alloc_size, GFP_KERNEL);
>   if (!new)
>   goto fail;
>   edid = new;
> @@ -2300,7 +2310,8 @@ struct edid *drm_do_get_edid(struct drm_connector 
> *connector,
>   if (invalid_blocks) {
>   connector_bad_edid(connector, edid, edid_block_count(edid));
>  
> - edid = edid_filter_invalid_blocks(edid, invalid_blocks);
> + edid = edid_filter_invalid_blocks(edid, invalid_blocks,
> +   _size);
>   }
>  
>  ok:
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel


Re: [PATCH v2 14/15] drm/edid: take HF-EEODB extension count into account

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:44AM +0300, Jani Nikula wrote:
> Take the HF-EEODB extension count override into account.
> 
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/drm_edid.c | 13 +
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 5cac357e50b0..b7b1f0639115 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1629,6 +1629,19 @@ static int drm_edid_block_count(const struct drm_edid 
> *drm_edid)
>   /* Starting point */
>   num_blocks = edid_block_count(drm_edid->edid);
>  
> + /* HF-EEODB override */
> + if (drm_edid->size >= edid_size_by_blocks(2)) {
> + int eeodb;
> +
> + /*
> +  * Note: HF-EEODB may specify a smaller extension count than the
> +  * regular one. Unlike in buffer allocation, here we can use it.
> +  */

Such a sink would be in violation of the spec. But the spec does
explicitly say sources are to ignore the normal ext count in those
cases. So this would seem to do what the spec asks of us.

Reviewed-by: Ville Syrjälä 

> + eeodb = edid_hfeeodb_block_count(drm_edid->edid);
> + if (eeodb)
> + num_blocks = eeodb;
> + }
> +
>   /* Limit by allocated size */
>   num_blocks = min(num_blocks, (int)drm_edid->size / EDID_LENGTH);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel


Re: [PATCH v2 13/15] drm/edid: add HF-EEODB support to EDID read and allocation

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:43AM +0300, Jani Nikula wrote:
> HDMI 2.1 section 10.3.6 defines an HDMI Forum EDID Extension Override
> Data Block, which may contain a different extension count than the base
> block claims. Add support for reading more EDID data if available. The
> extra blocks aren't parsed yet, though.
> 
> Hard-coding the EEODB parsing instead of using the iterators we have is
> a bit of a bummer, but we have to be able to do this on a partially
> allocated EDID while reading it.
> 
> v2:
> - Check for CEA Data Block Collection size (Ville)
> - Amend commit message and comment about hard-coded parsing
> 
> Signed-off-by: Jani Nikula 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/drm_edid.c | 89 --
>  1 file changed, 86 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 77ec5b0e436d..5cac357e50b0 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1581,6 +1581,15 @@ static bool version_greater(const struct drm_edid 
> *drm_edid,
>   (edid->version == version && edid->revision > revision);
>  }
>  
> +static int edid_hfeeodb_extension_block_count(const struct edid *edid);
> +
> +static int edid_hfeeodb_block_count(const struct edid *edid)
> +{
> + int eeodb = edid_hfeeodb_extension_block_count(edid);
> +
> + return eeodb ? eeodb + 1 : 0;
> +}
> +
>  static int edid_extension_block_count(const struct edid *edid)
>  {
>   return edid->extensions;
> @@ -2026,6 +2035,11 @@ static struct edid *edid_filter_invalid_blocks(struct 
> edid *edid,
>   struct edid *new;
>   int i, valid_blocks = 0;
>  
> + /*
> +  * Note: If the EDID uses HF-EEODB, but has invalid blocks, we'll revert
> +  * back to regular extension count here. We don't want to start
> +  * modifying the HF-EEODB extension too.
> +  */
>   for (i = 0; i < edid_block_count(edid); i++) {
>   const void *src_block = edid_block_data(edid, i);
>  
> @@ -2235,7 +2249,7 @@ static struct edid *_drm_do_get_edid(struct 
> drm_connector *connector,
>size_t *size)
>  {
>   enum edid_block_status status;
> - int i, invalid_blocks = 0;
> + int i, num_blocks, invalid_blocks = 0;
>   struct edid *edid, *new;
>   size_t alloc_size = EDID_LENGTH;
>  
> @@ -2277,7 +2291,8 @@ static struct edid *_drm_do_get_edid(struct 
> drm_connector *connector,
>   goto fail;
>   edid = new;
>  
> - for (i = 1; i < edid_block_count(edid); i++) {
> + num_blocks = edid_block_count(edid);
> + for (i = 1; i < num_blocks; i++) {
>   void *block = (void *)edid_block_data(edid, i);
>  
>   status = edid_block_read(block, i, read_block, context);
> @@ -2288,11 +2303,31 @@ static struct edid *_drm_do_get_edid(struct 
> drm_connector *connector,
>   if (status == EDID_BLOCK_READ_FAIL)
>   goto fail;
>   invalid_blocks++;
> + } else if (i == 1) {
> + /*
> +  * If the first EDID extension is a CTA extension, and
> +  * the first Data Block is HF-EEODB, override the
> +  * extension block count.
> +  *
> +  * Note: HF-EEODB could specify a smaller extension
> +  * count too, but we can't risk allocating a smaller
> +  * amount.
> +  */
> + int eeodb = edid_hfeeodb_block_count(edid);
> +
> + if (eeodb > num_blocks) {
> + num_blocks = eeodb;
> + alloc_size = edid_size_by_blocks(num_blocks);
> + new = krealloc(edid, alloc_size, GFP_KERNEL);
> + if (!new)
> + goto fail;
> + edid = new;
> + }
>   }
>   }
>  
>   if (invalid_blocks) {
> - connector_bad_edid(connector, edid, edid_block_count(edid));
> + connector_bad_edid(connector, edid, num_blocks);
>  
>   edid = edid_filter_invalid_blocks(edid, _size);
>   }
> @@ -3825,6 +3860,7 @@ static int add_detailed_modes(struct drm_connector 
> *connector,
>  #define CTA_EXT_DB_HDR_STATIC_METADATA   6
>  #define CTA_EXT_DB_420_VIDEO_DATA14
>  #define CTA_EXT_DB_420_VIDEO_CAP_MAP 15
> +#define CTA_EXT_DB_HF_EEODB  0x78
>  #define CTA_EXT_DB_HF_SCDB   0x79
>  
>  #define EDID_BASIC_AUDIO (1 << 6)
> @@ -4884,6 +4920,12 @@ static bool cea_db_is_hdmi_forum_vsdb(const struct 
> cea_db *db)
>   cea_db_payload_len(db) >= 7;
>  }
>  
> +static bool cea_db_is_hdmi_forum_eeodb(const void *db)
> +{
> + return cea_db_is_extended_tag(db, CTA_EXT_DB_HF_EEODB) 

Re: [PATCH v2 12/15] drm/edid: do invalid block filtering in-place

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:42AM +0300, Jani Nikula wrote:
> Rewrite edid_filter_invalid_blocks() to filter invalid blocks
> in-place. The main motivation is to not rely on passed in information on
> invalid block count or the allocation size, which will be helpful in
> follow-up work on HF-EEODB.
> 
> Signed-off-by: Jani Nikula 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/drm_edid.c | 43 --
>  1 file changed, 23 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 4e788c5cbf25..77ec5b0e436d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2020,33 +2020,37 @@ bool drm_edid_is_valid(struct edid *edid)
>  }
>  EXPORT_SYMBOL(drm_edid_is_valid);
>  
> -static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
> -int invalid_blocks,
> +static struct edid *edid_filter_invalid_blocks(struct edid *edid,
>  size_t *alloc_size)
>  {
> - struct edid *new, *dest_block;
> - int valid_extensions = edid->extensions - invalid_blocks;
> - int i;
> + struct edid *new;
> + int i, valid_blocks = 0;
>  
> - *alloc_size = edid_size_by_blocks(valid_extensions + 1);
> + for (i = 0; i < edid_block_count(edid); i++) {
> + const void *src_block = edid_block_data(edid, i);
>  
> - new = kmalloc(*alloc_size, GFP_KERNEL);
> - if (!new)
> - goto out;
> + if (edid_block_valid(src_block, i == 0)) {
> + void *dst_block = (void *)edid_block_data(edid, 
> valid_blocks);
>  
> - dest_block = new;
> - for (i = 0; i < edid_block_count(edid); i++) {
> - const void *block = edid_block_data(edid, i);
> + memmove(dst_block, src_block, EDID_LENGTH);
> + valid_blocks++;
> + }
> + }
>  
> - if (edid_block_valid(block, i == 0))
> - memcpy(dest_block++, block, EDID_LENGTH);
> + /* We already trusted the base block to be valid here... */
> + if (WARN_ON(!valid_blocks)) {
> + kfree(edid);
> + return NULL;
>   }
>  
> - new->extensions = valid_extensions;
> - new->checksum = edid_block_compute_checksum(new);
> + edid->extensions = valid_blocks - 1;
> + edid->checksum = edid_block_compute_checksum(edid);
>  
> -out:
> - kfree(edid);
> + *alloc_size = edid_size_by_blocks(valid_blocks);
> +
> + new = krealloc(edid, *alloc_size, GFP_KERNEL);
> + if (!new)
> + kfree(edid);
>  
>   return new;
>  }
> @@ -2290,8 +2294,7 @@ static struct edid *_drm_do_get_edid(struct 
> drm_connector *connector,
>   if (invalid_blocks) {
>   connector_bad_edid(connector, edid, edid_block_count(edid));
>  
> - edid = edid_filter_invalid_blocks(edid, invalid_blocks,
> -   _size);
> + edid = edid_filter_invalid_blocks(edid, _size);
>   }
>  
>  ok:
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel


Re: [PATCH v2 11/15] drm/i915/bios: convert intel_bios_init_panel() to drm_edid

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:41AM +0300, Jani Nikula wrote:
> Try to use struct drm_edid where possible, even if having to fall back
> to looking into struct edid down low via drm_edid_raw().
> 
> Signed-off-by: Jani Nikula 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/i915/display/intel_bios.c | 23 ---
>  drivers/gpu/drm/i915/display/intel_bios.h |  4 ++--
>  drivers/gpu/drm/i915/display/intel_dp.c   |  2 +-
>  drivers/gpu/drm/i915/display/intel_lvds.c |  2 +-
>  4 files changed, 16 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
> b/drivers/gpu/drm/i915/display/intel_bios.c
> index c42b9e7d0dce..be0b4264d526 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.c
> +++ b/drivers/gpu/drm/i915/display/intel_bios.c
> @@ -604,13 +604,13 @@ get_lfp_data_tail(const struct bdb_lvds_lfp_data *data,
>  }
>  
>  static int opregion_get_panel_type(struct drm_i915_private *i915,
> -const struct edid *edid)
> +const struct drm_edid *drm_edid)
>  {
>   return intel_opregion_get_panel_type(i915);
>  }
>  
>  static int vbt_get_panel_type(struct drm_i915_private *i915,
> -   const struct edid *edid)
> +   const struct drm_edid *drm_edid)
>  {
>   const struct bdb_lvds_options *lvds_options;
>  
> @@ -629,12 +629,13 @@ static int vbt_get_panel_type(struct drm_i915_private 
> *i915,
>  }
>  
>  static int pnpid_get_panel_type(struct drm_i915_private *i915,
> - const struct edid *edid)
> + const struct drm_edid *drm_edid)
>  {
>   const struct bdb_lvds_lfp_data *data;
>   const struct bdb_lvds_lfp_data_ptrs *ptrs;
>   const struct lvds_pnp_id *edid_id;
>   struct lvds_pnp_id edid_id_nodate;
> + const struct edid *edid = drm_edid_raw(drm_edid); /* FIXME */
>   int i, best = -1;
>  
>   if (!edid)
> @@ -675,7 +676,7 @@ static int pnpid_get_panel_type(struct drm_i915_private 
> *i915,
>  }
>  
>  static int fallback_get_panel_type(struct drm_i915_private *i915,
> -const struct edid *edid)
> +const struct drm_edid *drm_edid)
>  {
>   return 0;
>  }
> @@ -688,12 +689,12 @@ enum panel_type {
>  };
>  
>  static int get_panel_type(struct drm_i915_private *i915,
> -   const struct edid *edid)
> +   const struct drm_edid *drm_edid)
>  {
>   struct {
>   const char *name;
>   int (*get_panel_type)(struct drm_i915_private *i915,
> -   const struct edid *edid);
> +   const struct drm_edid *drm_edid);
>   int panel_type;
>   } panel_types[] = {
>   [PANEL_TYPE_OPREGION] = {
> @@ -716,7 +717,7 @@ static int get_panel_type(struct drm_i915_private *i915,
>   int i;
>  
>   for (i = 0; i < ARRAY_SIZE(panel_types); i++) {
> - panel_types[i].panel_type = panel_types[i].get_panel_type(i915, 
> edid);
> + panel_types[i].panel_type = panel_types[i].get_panel_type(i915, 
> drm_edid);
>  
>   drm_WARN_ON(>drm, panel_types[i].panel_type > 0xf &&
>   panel_types[i].panel_type != 0xff);
> @@ -747,7 +748,7 @@ static int get_panel_type(struct drm_i915_private *i915,
>  static void
>  parse_panel_options(struct drm_i915_private *i915,
>   struct intel_panel *panel,
> - const struct edid *edid)
> + const struct drm_edid *drm_edid)
>  {
>   const struct bdb_lvds_options *lvds_options;
>   int panel_type;
> @@ -759,7 +760,7 @@ parse_panel_options(struct drm_i915_private *i915,
>  
>   panel->vbt.lvds_dither = lvds_options->pixel_dither;
>  
> - panel_type = get_panel_type(i915, edid);
> + panel_type = get_panel_type(i915, drm_edid);
>  
>   panel->vbt.panel_type = panel_type;
>  
> @@ -3092,11 +3093,11 @@ void intel_bios_init(struct drm_i915_private *i915)
>  
>  void intel_bios_init_panel(struct drm_i915_private *i915,
>  struct intel_panel *panel,
> -const struct edid *edid)
> +const struct drm_edid *drm_edid)
>  {
>   init_vbt_panel_defaults(panel);
>  
> - parse_panel_options(i915, panel, edid);
> + parse_panel_options(i915, panel, drm_edid);
>   parse_generic_dtd(i915, panel);
>   parse_lfp_data(i915, panel);
>   parse_lfp_backlight(i915, panel);
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.h 
> b/drivers/gpu/drm/i915/display/intel_bios.h
> index b112200ae0a0..7bcc818e8d80 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.h
> +++ b/drivers/gpu/drm/i915/display/intel_bios.h
> @@ -32,8 +32,8 @@
>  
>  #include 
>  
> +struct drm_edid;
>  struct drm_i915_private;
> -struct edid;
>  struct 

Re: [PATCH v2 09/15] drm/edid: add drm_edid_raw() to access the raw EDID data

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:39AM +0300, Jani Nikula wrote:
> Unfortunately, there are still plenty of interfaces around that require
> a struct edid pointer, and it's impossible to change them all at
> once. Add an accessor to the raw EDID data to help the transition.
> 
> While there are no such cases now, be defensive against raw EDID
> extension count indicating bigger EDID than is actually allocated.
> 
> Signed-off-by: Jani Nikula 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/drm_edid.c | 26 ++
>  include/drm/drm_edid.h |  1 +
>  2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 952724788963..4e788c5cbf25 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2333,6 +2333,32 @@ struct edid *drm_do_get_edid(struct drm_connector 
> *connector,
>  }
>  EXPORT_SYMBOL_GPL(drm_do_get_edid);
>  
> +/**
> + * drm_edid_raw - Get a pointer to the raw EDID data.
> + * @drm_edid: drm_edid container
> + *
> + * Get a pointer to the raw EDID data.
> + *
> + * This is for transition only. Avoid using this like the plague.
> + *
> + * Return: Pointer to raw EDID data.
> + */
> +const struct edid *drm_edid_raw(const struct drm_edid *drm_edid)
> +{
> + if (!drm_edid || !drm_edid->size)
> + return NULL;
> +
> + /*
> +  * Do not return pointers where relying on EDID extension count would
> +  * lead to buffer overflow.
> +  */
> + if (WARN_ON(edid_size(drm_edid->edid) > drm_edid->size))
> + return NULL;
> +
> + return drm_edid->edid;
> +}
> +EXPORT_SYMBOL(drm_edid_raw);
> +
>  /* Allocate struct drm_edid container *without* duplicating the edid data */
>  static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
>  {
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index aeb2fa95bc04..2181977ae683 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -597,6 +597,7 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>  const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
>  const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
>  void drm_edid_free(const struct drm_edid *drm_edid);
> +const struct edid *drm_edid_raw(const struct drm_edid *drm_edid);
>  const struct drm_edid *drm_edid_read(struct drm_connector *connector);
>  const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
>struct i2c_adapter *adapter);
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel


Re: [PATCH 2/3] drm/panel: panel-dsi-cm: Use backlight helpers

2022-06-10 Thread Sam Ravnborg
Hi Stephen.
On Fri, Jun 10, 2022 at 07:47:20PM +0200, Stephen Kitt wrote:
> Hi Sebastian,
> 
> On Thu, 9 Jun 2022 23:52:36 +0200, Sebastian Reichel
>  wrote:
> > On Tue, Jun 07, 2022 at 08:20:25PM +0200, Stephen Kitt wrote:
> > > diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c
> > > b/drivers/gpu/drm/panel/panel-dsi-cm.c index b58cb064975f..aa36dc6cedd3
> > > 100644 --- a/drivers/gpu/drm/panel/panel-dsi-cm.c
> > > +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
> > > @@ -86,16 +86,10 @@ static void dsicm_bl_power(struct panel_drv_data
> > > *ddata, bool enable) return;
> > >  
> > >   if (enable) {
> > > - backlight->props.fb_blank = FB_BLANK_UNBLANK;
> > > - backlight->props.state = ~(BL_CORE_FBBLANK |
> > > BL_CORE_SUSPENDED);
> > > - backlight->props.power = FB_BLANK_UNBLANK;
> > > + backlight_enable(backlight);
> > >   } else {
> > > - backlight->props.fb_blank = FB_BLANK_NORMAL;
> > > - backlight->props.power = FB_BLANK_POWERDOWN;
> > > - backlight->props.state |= BL_CORE_FBBLANK |
> > > BL_CORE_SUSPENDED;
> > > + backlight_disable(backlight);
> > >   }  
> > 
> > The brackets can be removed now. Otherwise:
> 
> > 
> > Reviewed-by: Sebastian Reichel 
> 
> Thanks, I’ll wait a little more to see if there are any other reviews of the
> patches and then push a v2 with that fix.
It would be very nice if you could kill all uses of FB_BLANK in the
drivers/gpu/drm/panel/* drivers, and post them as one series.
This is long overdue to introduce the backlight helpers.

The three you posted is already a nice step forward, and there may be
more panel drivers I have missed.

Sam


Re: [PATCH v2 10/15] drm/i915/edid: convert DP, HDMI and LVDS to drm_edid

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:40AM +0300, Jani Nikula wrote:
> Convert all the connectors that use cached connector edid and
> detect_edid to drm_edid.
> 
> Signed-off-by: Jani Nikula 
> ---
>  .../gpu/drm/i915/display/intel_connector.c|  4 +-
>  .../drm/i915/display/intel_display_types.h|  4 +-
>  drivers/gpu/drm/i915/display/intel_dp.c   | 74 ++-
>  drivers/gpu/drm/i915/display/intel_hdmi.c | 26 ---
>  drivers/gpu/drm/i915/display/intel_lvds.c | 37 +-
>  5 files changed, 79 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_connector.c 
> b/drivers/gpu/drm/i915/display/intel_connector.c
> index 1dcc268927a2..d83b2a64f618 100644
> --- a/drivers/gpu/drm/i915/display/intel_connector.c
> +++ b/drivers/gpu/drm/i915/display/intel_connector.c
> @@ -95,12 +95,12 @@ void intel_connector_destroy(struct drm_connector 
> *connector)
>  {
>   struct intel_connector *intel_connector = to_intel_connector(connector);
>  
> - kfree(intel_connector->detect_edid);
> + drm_edid_free(intel_connector->detect_edid);
>  
>   intel_hdcp_cleanup(intel_connector);
>  
>   if (!IS_ERR_OR_NULL(intel_connector->edid))
> - kfree(intel_connector->edid);
> + drm_edid_free(intel_connector->edid);
>  
>   intel_panel_fini(intel_connector);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 9b44358e8d9e..dffbc7d59587 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -590,8 +590,8 @@ struct intel_connector {
>   struct intel_panel panel;
>  
>   /* Cached EDID for eDP and LVDS. May hold ERR_PTR for invalid EDID. */
> - struct edid *edid;
> - struct edid *detect_edid;
> + const struct drm_edid *edid;
> + const struct drm_edid *detect_edid;
>  
>   /* Number of times hotplug detection was tried after an HPD interrupt */
>   int hotplug_retries;
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index e198c6d7e3b5..64b6481225f1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -3534,12 +3534,11 @@ static u8 intel_dp_autotest_edid(struct intel_dp 
> *intel_dp)
>   intel_dp->aux.i2c_defer_count);
>   intel_dp->compliance.test_data.edid = 
> INTEL_DP_RESOLUTION_FAILSAFE;
>   } else {
> - struct edid *block = intel_connector->detect_edid;
> + /* FIXME: Get rid of drm_edid_raw() */
> + const struct edid *block = 
> drm_edid_raw(intel_connector->detect_edid);
>  
> - /* We have to write the checksum
> -  * of the last block read
> -  */
> - block += intel_connector->detect_edid->extensions;
> + /* We have to write the checksum of the last block read */
> + block += block->extensions;
>  
>   if (drm_dp_dpcd_writeb(_dp->aux, DP_TEST_EDID_CHECKSUM,
>  block->checksum) <= 0)
> @@ -4418,7 +4417,7 @@ bool intel_digital_port_connected(struct intel_encoder 
> *encoder)
>   return is_connected;
>  }
>  
> -static struct edid *
> +static const struct drm_edid *
>  intel_dp_get_edid(struct intel_dp *intel_dp)
>  {
>   struct intel_connector *intel_connector = intel_dp->attached_connector;
> @@ -4429,18 +4428,22 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
>   if (IS_ERR(intel_connector->edid))
>   return NULL;
>  
> - return drm_edid_duplicate(intel_connector->edid);
> + return drm_edid_dup(intel_connector->edid);
>   } else
> - return drm_get_edid(_connector->base,
> - _dp->aux.ddc);
> + return drm_edid_read_ddc(_connector->base,
> +  _dp->aux.ddc);
>  }
>  
>  static void
>  intel_dp_update_dfp(struct intel_dp *intel_dp,
> - const struct edid *edid)
> + const struct drm_edid *drm_edid)
>  {
>   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>   struct intel_connector *connector = intel_dp->attached_connector;
> + const struct edid *edid;
> +
> + /* FIXME: Get rid of drm_edid_raw() */
> + edid = drm_edid_raw(drm_edid);
>  
>   intel_dp->dfp.max_bpc =
>   drm_dp_downstream_max_bpc(intel_dp->dpcd,
> @@ -4540,21 +4543,24 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
>  {
>   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>   struct intel_connector *connector = intel_dp->attached_connector;
> - struct edid *edid;
> + const struct drm_edid *drm_edid;
> + const struct edid *edid;
>   bool vrr_capable;
>  
>   intel_dp_unset_edid(intel_dp);
> - edid = 

Re: [PATCH v2 06/15] drm/edid: add drm_edid_connector_update()

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:36AM +0300, Jani Nikula wrote:
> Add a new function drm_edid_connector_update() to replace the
> combination of calls drm_connector_update_edid_property() and
> drm_add_edid_modes(). Usually they are called in the drivers in this
> order, however the former needs information from the latter.
> 
> Since the new drm_edid_read*() functions no longer call the connector
> updates directly, and the read and update are separated, we'll need this
> new function for the connector update.
> 
> This is all in drm_edid.c simply to keep struct drm_edid opaque.
> 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/drm_connector.c |  2 +
>  drivers/gpu/drm/drm_edid.c  | 71 +++--
>  include/drm/drm_edid.h  |  2 +
>  3 files changed, 71 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 1c48d162c77e..ae9c640a641a 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -2088,6 +2088,8 @@ EXPORT_SYMBOL(drm_connector_set_tile_property);
>   * set the connector's tile property here. See 
> drm_connector_set_tile_property()
>   * for more details.
>   *
> + * This function is deprecated. Use drm_edid_connector_update() instead.
> + *
>   * Returns:
>   * Zero on success, negative errno on failure.
>   */
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2bdaf1e34a9d..952724788963 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -6143,8 +6143,8 @@ static int add_displayid_detailed_modes(struct 
> drm_connector *connector,
>   return num_modes;
>  }
>  
> -static int drm_edid_connector_update(struct drm_connector *connector,
> -  const struct drm_edid *drm_edid)
> +static int _drm_edid_connector_update(struct drm_connector *connector,
> +   const struct drm_edid *drm_edid)
>  {
>   int num_modes = 0;
>   u32 quirks;
> @@ -6207,6 +6207,67 @@ static int drm_edid_connector_update(struct 
> drm_connector *connector,
>   return num_modes;
>  }
>  
> +static void _drm_update_tile_info(struct drm_connector *connector,
> +   const struct drm_edid *drm_edid);
> +
> +/**
> + * drm_edid_connector_update - Update connector information from EDID
> + * @connector: Connector
> + * @drm_edid: EDID
> + *
> + * Update the connector mode list, display info, ELD, HDR metadata, relevant
> + * properties, etc. from the passed in EDID.
> + *
> + * If EDID is NULL, reset the information.
> + *
> + * Return: The number of modes added or 0 if we couldn't find any.
> + */
> +int drm_edid_connector_update(struct drm_connector *connector,
> +   const struct drm_edid *drm_edid)
> +{
> + struct drm_device *dev = connector->dev;
> + const struct edid *old_edid = connector->edid_blob_ptr ?
> + connector->edid_blob_ptr->data : NULL;
> + const struct edid *edid = drm_edid ? drm_edid->edid : NULL;
> + size_t size = drm_edid ? drm_edid->size : 0;
> + int count, ret;
> +
> + count = _drm_edid_connector_update(connector, drm_edid);
> +
> + _drm_update_tile_info(connector, drm_edid);
> +
> + if (old_edid && !drm_edid_are_equal(edid, old_edid)) {

The old_edid check looks a bit odd. Can't really see why we'd not
want to bump the epoch counter when we go from not having and EDID
to having one. This issue already seems to exist in the current code,
although that one also skips the epoch counter bump if the new EDID
is missing, so even more odd.

This also brings me to the slight annoynace of having this code
duplicated in two places. I worry we'll end up accumulating different
bugs in each copy. Can't we refactor to have just one copy?

> + connector->epoch_counter++;
> +
> + drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID changed, epoch counter 
> %llu\n",
> + connector->base.id, connector->name,
> + connector->epoch_counter);
> + }
> +
> + ret = drm_property_replace_global_blob(dev, >edid_blob_ptr,
> +size, edid,
> +>base,
> +dev->mode_config.edid_property);
> + if (ret)
> + drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID property update failed 
> (%d)\n",
> + connector->base.id, connector->name, ret);
> +
> + ret = drm_object_property_set_value(>base,
> + 
> dev->mode_config.non_desktop_property,
> + 
> connector->display_info.non_desktop);
> + if (ret)
> + drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Non-desktop property update 
> failed (%d)\n",
> + connector->base.id, 

Re: [PATCH 2/3] drm/panel: panel-dsi-cm: Use backlight helpers

2022-06-10 Thread Stephen Kitt
Hi Sebastian,

On Thu, 9 Jun 2022 23:52:36 +0200, Sebastian Reichel
 wrote:
> On Tue, Jun 07, 2022 at 08:20:25PM +0200, Stephen Kitt wrote:
> > diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c
> > b/drivers/gpu/drm/panel/panel-dsi-cm.c index b58cb064975f..aa36dc6cedd3
> > 100644 --- a/drivers/gpu/drm/panel/panel-dsi-cm.c
> > +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
> > @@ -86,16 +86,10 @@ static void dsicm_bl_power(struct panel_drv_data
> > *ddata, bool enable) return;
> >  
> > if (enable) {
> > -   backlight->props.fb_blank = FB_BLANK_UNBLANK;
> > -   backlight->props.state = ~(BL_CORE_FBBLANK |
> > BL_CORE_SUSPENDED);
> > -   backlight->props.power = FB_BLANK_UNBLANK;
> > +   backlight_enable(backlight);
> > } else {
> > -   backlight->props.fb_blank = FB_BLANK_NORMAL;
> > -   backlight->props.power = FB_BLANK_POWERDOWN;
> > -   backlight->props.state |= BL_CORE_FBBLANK |
> > BL_CORE_SUSPENDED;
> > +   backlight_disable(backlight);
> > }  
> 
> The brackets can be removed now. Otherwise:

> 
> Reviewed-by: Sebastian Reichel 

Thanks, I’ll wait a little more to see if there are any other reviews of the
patches and then push a v2 with that fix.

Regards,

Stephen


pgpyW8BdT9F89.pgp
Description: OpenPGP digital signature


Re: [PATCH v2 03/11] clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw()

2022-06-10 Thread Stephen Boyd
Quoting Marijn Suijten (2022-06-10 00:46:32)
> On 2022-06-09 15:12:09, Stephen Boyd wrote:
> > Quoting Dmitry Baryshkov (2022-06-02 03:20:19)
> > > On Thu, 2 Jun 2022 at 01:07, Marijn Suijten
> > >  wrote:
> > > > diff --git a/drivers/clk/clk-fixed-factor.c 
> > > > b/drivers/clk/clk-fixed-factor.c
> > > > index 54942d758ee6..fabb98d0cdb2 100644
> > > > --- a/drivers/clk/clk-fixed-factor.c
> > > > +++ b/drivers/clk/clk-fixed-factor.c
> > > > @@ -148,17 +151,50 @@ struct clk_hw 
> > > > *devm_clk_hw_register_fixed_factor_index(struct device *dev,
> > > > const char *name, unsigned int index, unsigned long 
> > > > flags,
> > > > unsigned int mult, unsigned int div)
> > > >  {
> > > > -   return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, 
> > > > index,
> > > > - flags, mult, div, true);
> > > > +   return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, 
> > > > NULL,
> > > > + index, flags, mult, div, 
> > > > true);
> > > 
> > > Here (and several times later) you are inserting an argument and then
> > > moving arguments to the next line. My slight preference would be to
> > > just insert the arg (and maybe break the line if it gets too long) w/o
> > > touching the next lines.
> 
> That'll definitely look odd, as we'll end up with index floating on a
> single line, all on its own.

Pretty sure Dmitry is suggesting to make the line longer, not put the
index on a line by itself. Ignore the 80-column limit.

> 
> > I'd just add the argument at the end because when it is added in the
> > middle it makes the diff more difficult to read.
> 
> How strong is this feeling, against keeping argument ordering consistent
> with other implementations of similar __clk_hw_register_* functions?
> 

Not super strong. Just try to minimize the diff to make the reviewer's
job easier. In this case it would be inserting NULL before 'index' and
not modifying the next line so the diff is one line instead of two.


Re: [PATCH v2 02/15] drm/edid: abstract cea data block collection size

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:32AM +0300, Jani Nikula wrote:
> Add a function to get the cea data block collection size.
> 
> Cc: Ville Syrjälä 
> Signed-off-by: Jani Nikula 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/drm_edid.c | 24 +---
>  1 file changed, 21 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index c57f6333ea7d..002816509fc8 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4482,6 +4482,20 @@ __cea_db_iter_current_block(const struct cea_db_iter 
> *iter)
>   return NULL;
>  }
>  
> +/*
> + * References:
> + * - CTA-861-H section 7.3.3 CTA Extension Version 3
> + */
> +static int cea_db_collection_size(const u8 *cta)
> +{
> + u8 d = cta[2];
> +
> + if (d < 4 || d > 127)
> + return 0;
> +
> + return d - 4;
> +}
> +
>  /*
>   * References:
>   * - VESA E-EDID v1.4
> @@ -4492,15 +4506,19 @@ static const void *__cea_db_iter_edid_next(struct 
> cea_db_iter *iter)
>   const u8 *ext;
>  
>   drm_edid_iter_for_each(ext, >edid_iter) {
> + int size;
> +
>   /* Only support CTA Extension revision 3+ */
>   if (ext[0] != CEA_EXT || cea_revision(ext) < 3)
>   continue;
>  
> - iter->index = 4;
> - iter->end = ext[2];
> - if (iter->end < 4 || iter->end > 127)
> + size = cea_db_collection_size(ext);
> + if (!size)
>   continue;
>  
> + iter->index = 4;
> + iter->end = iter->index + size;
> +
>   return ext;
>   }
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel


Re: [PATCH v2 01/15] drm/edid: fix CTA data block collection size for CTA version 3

2022-06-10 Thread Ville Syrjälä
On Wed, Jun 08, 2022 at 10:50:31AM +0300, Jani Nikula wrote:
> The CTA Data Block Collection is valid only for CTA extension version
> 3. In versions 1 and 2, it is a reserved block, which we ignore.
> 
> The DTD start offset (byte 2, or d in CTA-861 spec), which determines
> the CTA Data Block Collection size, is specified slightly differently
> for different versions:
> 
> Version 1:
> d = offset for the byte following the reserved data block. If no
> data is provided in the reserved data block, then d=4. If no DTDs
> are provided, then d=0
> 
> Version 2:
> d = offset for the byte following the reserved data block. If no
> data is provided in the reserved data block, then d=4. If d=0, then
> no detailed timing descriptors are provided, and no data is provided
> in the reserved data block.
> 
> Version 3:
> d = offset for the byte following the data block collection. If no
> data is provided in the data block collection, then d=4. If d=0,
> then no detailed timing descriptors are provided, and no data is
> provided in the data block collection.
> 
> Ever since commit 9e50b9d55e9c ("drm: edid: Add some bounds checking"),
> we've interpreted 0 to mean there are no DTDs but it's all Data
> Blocks. Per the spec, Data Blocks are only valid for version 3, where we
> should interpret 0 to mean there are no data blocks.
> 
> Follow the spec (and hope the EDIDs follow it too).
> 
> Cc: Ville Syrjälä 
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/drm_edid.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 929fc0e46751..c57f6333ea7d 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4498,8 +4498,6 @@ static const void *__cea_db_iter_edid_next(struct 
> cea_db_iter *iter)
>  
>   iter->index = 4;
>   iter->end = ext[2];
> - if (iter->end == 0)
> - iter->end = 127;

Not really sure how I came up with this interpretation of the spec.

Looks like I at least fixed up the 18byte descriptor parsing
correctly in commit 7304b9810a73 ("drm/edid: Check the number
of detailed timing descriptors in the CEA ext block")

Reviewed-by: Ville Syrjälä 

>   if (iter->end < 4 || iter->end > 127)
>   continue;
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel


[PATCH] drm/bridge: tc358767: don't fixup mode polarity

2022-06-10 Thread Lucas Stach
It doesn't always work, as there is just a single adjusted mode, so if
parts of the display pipeline disagree on the required sync polarity
it's possible to end up with a invalid config. However it also isn't
necessary for this bridge chip, as the DPI interface has a configurable
sync polarity, so we can just set it up to match the mode.

Signed-off-by: Lucas Stach 
---
 drivers/gpu/drm/bridge/tc358767.c | 27 ++-
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358767.c 
b/drivers/gpu/drm/bridge/tc358767.c
index 485717c8f0b4..bd2cae711ca0 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -889,6 +889,7 @@ static int tc_set_edp_video_mode(struct tc_data *tc,
u32 dp0_syncval;
u32 bits_per_pixel = 24;
u32 in_bw, out_bw;
+   u32 dpipxlfmt;
 
/*
 * Recommended maximum number of symbols transferred in a transfer unit:
@@ -938,10 +939,15 @@ static int tc_set_edp_video_mode(struct tc_data *tc,
if (ret)
return ret;
 
-   ret = regmap_write(tc->regmap, DPIPXLFMT,
-  VS_POL_ACTIVE_LOW | HS_POL_ACTIVE_LOW |
-  DE_POL_ACTIVE_HIGH | SUB_CFG_TYPE_CONFIG1 |
-  DPI_BPP_RGB888);
+   dpipxlfmt = DE_POL_ACTIVE_HIGH | SUB_CFG_TYPE_CONFIG1 | DPI_BPP_RGB888;
+
+   if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+   dpipxlfmt |= VS_POL_ACTIVE_LOW;
+
+   if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+   dpipxlfmt |= HS_POL_ACTIVE_LOW;
+
+   ret = regmap_write(tc->regmap, DPIPXLFMT, dpipxlfmt);
if (ret)
return ret;
 
@@ -1471,18 +1477,6 @@ tc_edp_bridge_atomic_disable(struct drm_bridge *bridge,
dev_err(tc->dev, "main link disable error: %d\n", ret);
 }
 
-static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
-const struct drm_display_mode *mode,
-struct drm_display_mode *adj)
-{
-   /* Fixup sync polarities, both hsync and vsync are active low */
-   adj->flags = mode->flags;
-   adj->flags |= (DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
-   adj->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
-
-   return true;
-}
-
 static int tc_common_atomic_check(struct drm_bridge *bridge,
  struct drm_bridge_state *bridge_state,
  struct drm_crtc_state *crtc_state,
@@ -1758,7 +1752,6 @@ static const struct drm_bridge_funcs tc_edp_bridge_funcs 
= {
.atomic_check = tc_edp_atomic_check,
.atomic_enable = tc_edp_bridge_atomic_enable,
.atomic_disable = tc_edp_bridge_atomic_disable,
-   .mode_fixup = tc_bridge_mode_fixup,
.detect = tc_bridge_detect,
.get_edid = tc_get_edid,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
-- 
2.30.2



Re: [Intel-gfx] [PATCH v7] drm/i915/display: disable HPD workers before display driver unregister

2022-06-10 Thread Ville Syrjälä
On Fri, Jun 10, 2022 at 06:00:24PM +0200, Andrzej Hajda wrote:
> Handling HPD during driver removal is pointless, and can cause different
> use-after-free/concurrency issues:
> 1. Setup of deferred fbdev after fbdev unregistration.
> 2. Access to DP-AUX after DP-AUX removal.
> 
> Below stacktraces of both cases observed on CI:
> 
> [272.634530] general protection fault, probably for non-canonical address 
> 0x6b6b6b6b6b6b6b6b:  [#1] PREEMPT SMP NOPTI
> [272.634536] CPU: 0 PID: 6030 Comm: i915_selftest Tainted: G U
> 5.18.0-rc5-CI_DRM_11603-g12dccf4f5eef+ #1
> [272.634541] Hardware name: Intel Corporation Raptor Lake Client 
> Platform/RPL-S ADP-S DDR5 UDIMM CRB, BIOS RPLSFWI1.R00.2397.A01.2109300731 
> 09/30/2021
> [272.634545] RIP: 0010:fb_do_apertures_overlap.part.14+0x26/0x60
> ...
> [272.634582] Call Trace:
> [272.634583]  
> [272.634585]  do_remove_conflicting_framebuffers+0x59/0xa0
> [272.634589]  remove_conflicting_framebuffers+0x2d/0xc0
> [272.634592]  remove_conflicting_pci_framebuffers+0xc8/0x110
> [272.634595]  drm_aperture_remove_conflicting_pci_framebuffers+0x52/0x70
> [272.634604]  i915_driver_probe+0x63a/0xdd0 [i915]
> 
> [283.405824] cpu_latency_qos_update_request called for unknown object
> [283.405866] WARNING: CPU: 2 PID: 240 at kernel/power/qos.c:296 
> cpu_latency_qos_update_request+0x2d/0x100
> [283.405912] CPU: 2 PID: 240 Comm: kworker/u64:9 Not tainted 
> 5.18.0-rc6-Patchwork_103738v3-g1672d1c43e43+ #1
> [283.405915] Hardware name: Intel Corporation Raptor Lake Client 
> Platform/RPL-S ADP-S DDR5 UDIMM CRB, BIOS RPLSFWI1.R00.2397.A01.2109300731 
> 09/30/2021
> [283.405916] Workqueue: i915-dp i915_digport_work_func [i915]
> [283.406020] RIP: 0010:cpu_latency_qos_update_request+0x2d/0x100
> ...
> [283.406040] Call Trace:
> [283.406041]  
> [283.406044]  intel_dp_aux_xfer+0x60e/0x8e0 [i915]
> [283.406131]  ? finish_swait+0x80/0x80
> [283.406139]  intel_dp_aux_transfer+0xc5/0x2b0 [i915]
> [283.406218]  drm_dp_dpcd_access+0x79/0x130 [drm_display_helper]
> [283.406227]  drm_dp_dpcd_read+0xe2/0xf0 [drm_display_helper]
> [283.406233]  intel_dp_hpd_pulse+0x134/0x570 [i915]
> [283.406308]  ? __down_killable+0x70/0x140
> [283.406313]  i915_digport_work_func+0xba/0x150 [i915]
> 
> Signed-off-by: Andrzej Hajda 
> ---
> Hi All,
> 
> I am not sure about changes in shutdown path, any comments welcome.
> I suspect suspend path have also some common bits, but I am little
> bit afraid of touching it.
> 
> Changes:
> v1 - v6:
> - chasing the bug appearing only on public CI.
> v7:
> - shutdown path adjusted (suggested by Jani)
> 
> Regards
> Andrzej
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 11 ---
>  drivers/gpu/drm/i915/i915_driver.c   |  5 ++---
>  2 files changed, 6 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 186b37925d23f2..f9952ee8289fb2 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -10490,13 +10490,6 @@ void intel_modeset_driver_remove_noirq(struct 
> drm_i915_private *i915)
>*/
>   intel_hpd_poll_fini(i915);
>  
> - /*
> -  * MST topology needs to be suspended so we don't have any calls to
> -  * fbdev after it's finalized. MST will be destroyed later as part of
> -  * drm_mode_config_cleanup()
> -  */
> - intel_dp_mst_suspend(i915);
> -
>   /* poll work can call into fbdev, hence clean that up afterwards */
>   intel_fbdev_fini(i915);
>  
> @@ -10588,6 +10581,10 @@ void intel_display_driver_unregister(struct 
> drm_i915_private *i915)
>   if (!HAS_DISPLAY(i915))
>   return;
>  
> + intel_dp_mst_suspend(i915);
> + intel_hpd_cancel_work(i915);
> + drm_kms_helper_poll_disable(>drm);
> +
>   intel_fbdev_unregister(i915);
>   intel_audio_deinit(i915);
>  
> diff --git a/drivers/gpu/drm/i915/i915_driver.c 
> b/drivers/gpu/drm/i915/i915_driver.c
> index d26dcca7e654aa..82cdccf072e2bc 100644
> --- a/drivers/gpu/drm/i915/i915_driver.c
> +++ b/drivers/gpu/drm/i915/i915_driver.c
> @@ -1070,15 +1070,14 @@ void i915_driver_shutdown(struct drm_i915_private 
> *i915)
>   i915_gem_suspend(i915);
>  
>   if (HAS_DISPLAY(i915)) {
> + intel_dp_mst_suspend(i915);
> + intel_hpd_cancel_work(i915);
>   drm_kms_helper_poll_disable(>drm);
>  
>   drm_atomic_helper_shutdown(>drm);

You can't suspend MST before this since this is what actually turns the
displays off.

The real chicken and egg sitaation is due to MST sideband depending
on HPD_IRQs to work, but we want to stop the rest of hotplug processing
before we shut down the displays to make sure fbdev/etc. doesn't light
them back up. 

If we didn't have MST sidband we could just turn off hotplug interrupts
ahead of time and flush the works, but with MST we need to keep the
interrupts alive. So I 

Re: [PATCH] dt-bindings: display: arm,malidp: remove bogus RQOS property

2022-06-10 Thread Rob Herring
On Thu, 09 Jun 2022 17:27:29 +0100, Andre Przywara wrote:
> As Liviu pointed out, the arm,malidp-arqos-high-level property
> mentioned in the original .txt binding was a mistake, and
> arm,malidp-arqos-value needs to take its place.
> 
> The binding commit ce6eb0253cba ("dt/bindings: display: Add optional
> property node define for Mali DP500") mentions the right name in the
> commit message, but has the wrong name in the diff.
> Commit d298e6a27a81 ("drm/arm/mali-dp: Add display QoS interface
> configuration for Mali DP500") uses the property in the driver, but uses
> the shorter name.
> 
> Remove the wrong property from the binding, and use the proper name in
> the example. The actual property was already documented properly.
> 
> Fixes: 2c8b082a3ab1 ("dt-bindings: display: convert Arm Mali-DP to DT schema")
> Link: 
> https://lore.kernel.org/linux-arm-kernel/ynumgeilublhb...@e110455-lin.cambridge.arm.com/
> Signed-off-by: Andre Przywara 
> Reported-by: Liviu Dudau 
> ---
>  Documentation/devicetree/bindings/display/arm,malidp.yaml | 7 +--
>  1 file changed, 1 insertion(+), 6 deletions(-)
> 

Applied, thanks!


Re: [git pull] drm fixes for 5.19-rc2

2022-06-10 Thread pr-tracker-bot
The pull request you sent on Fri, 10 Jun 2022 16:00:24 +1000:

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

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

Thank you!

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


Re: [PATCH] fbdev: atmel_lcdfb: Rework backlight status updates

2022-06-10 Thread Stephen Kitt
On Fri, 10 Jun 2022 10:49:55 +0100, Daniel Thompson
 wrote:
> On Thu, Jun 09, 2022 at 07:45:11PM +0200, Stephen Kitt wrote:
> > Hi Sam, Daniel,
> >
> > On Thu, 9 Jun 2022 19:30:57 +0200, Sam Ravnborg  wrote:
> >  
> > > thanks for taking care of all these backlight simplifications - this
> > > really helps to make the code simpler and more readable.  
> >
> > You’re welcome! I noticed fb_blank was deprecated and near enough unused,
> > and started digging...  
> 
> I saw Sam's comment and kinda wished I'd thought to say that... definitely
> good to see these things being tidied up.

Thanks! I saw the nice wrapper functions in backlight.h and couldn’t resist.

Regards,

Stephen


pgpL3_7dQWXRH.pgp
Description: OpenPGP digital signature


Re: [Intel-gfx] [RFC v3 1/3] drm/doc/rfc: VM_BIND feature design document

2022-06-10 Thread Niranjana Vishwanathapura

On Fri, Jun 10, 2022 at 11:18:14AM +0300, Lionel Landwerlin wrote:

On 10/06/2022 10:54, Niranjana Vishwanathapura wrote:

On Fri, Jun 10, 2022 at 09:53:24AM +0300, Lionel Landwerlin wrote:

On 09/06/2022 22:31, Niranjana Vishwanathapura wrote:

On Thu, Jun 09, 2022 at 05:49:09PM +0300, Lionel Landwerlin wrote:

  On 09/06/2022 00:55, Jason Ekstrand wrote:

    On Wed, Jun 8, 2022 at 4:44 PM Niranjana Vishwanathapura
     wrote:

  On Wed, Jun 08, 2022 at 08:33:25AM +0100, Tvrtko Ursulin wrote:
  >
  >
  >On 07/06/2022 22:32, Niranjana Vishwanathapura wrote:
  >>On Tue, Jun 07, 2022 at 11:18:11AM -0700, Niranjana 
Vishwanathapura

  wrote:
  >>>On Tue, Jun 07, 2022 at 12:12:03PM -0500, Jason 
Ekstrand wrote:

   On Fri, Jun 3, 2022 at 6:52 PM Niranjana Vishwanathapura
    wrote:
  
     On Fri, Jun 03, 2022 at 10:20:25AM +0300, Lionel 
Landwerlin

  wrote:
     >   On 02/06/2022 23:35, Jason Ekstrand wrote:
     >
     > On Thu, Jun 2, 2022 at 3:11 PM Niranjana 
Vishwanathapura

     >  wrote:
     >
     >   On Wed, Jun 01, 2022 at 01:28:36PM -0700, Matthew
  Brost wrote:
     >   >On Wed, Jun 01, 2022 at 05:25:49PM +0300, Lionel
  Landwerlin
     wrote:
     >   >> On 17/05/2022 21:32, Niranjana Vishwanathapura
  wrote:
     >   >> > +VM_BIND/UNBIND ioctl will immediately start
     binding/unbinding
     >   the mapping in an
     >   >> > +async worker. The binding and 
unbinding will

  work like a
     special
     >   GPU engine.
     >   >> > +The binding and unbinding operations are
  serialized and
     will
     >   wait on specified
     >   >> > +input fences before the operation 
and will signal

  the
     output
     >   fences upon the
     >   >> > +completion of the operation. Due to
  serialization,
     completion of
     >   an operation
     >   >> > +will also indicate that all 
previous operations

  are also
     >   complete.
     >   >>
     >   >> I guess we should avoid saying "will 
immediately

  start
     >   binding/unbinding" if
     >   >> there are fences involved.
     >   >>
     >   >> And the fact that it's happening in an async
  worker seem to
     imply
     >   it's not
     >   >> immediate.
     >   >>
     >
     >   Ok, will fix.
     >   This was added because in earlier design 
binding was

  deferred
     until
     >   next execbuff.
     >   But now it is non-deferred (immediate in 
that sense).

  But yah,
     this is
     >   confusing
     >   and will fix it.
     >
     >   >>
     >   >> I have a question on the behavior of the bind
  operation when
     no
     >   input fence
     >   >> is provided. Let say I do :
     >   >>
     >   >> VM_BIND (out_fence=fence1)
     >   >>
     >   >> VM_BIND (out_fence=fence2)
     >   >>
     >   >> VM_BIND (out_fence=fence3)
     >   >>
     >   >>
     >   >> In what order are the fences going to 
be signaled?

     >   >>
     >   >> In the order of VM_BIND ioctls? Or out 
of order?

     >   >>
     >   >> Because you wrote "serialized I assume 
it's : in

  order
     >   >>
     >
     >   Yes, in the order of VM_BIND/UNBIND 
ioctls. Note that

  bind and
     unbind
     >   will use
     >   the same queue and hence are ordered.
     >
     >   >>
     >   >> One thing I didn't realize is that 
because we only

  get one
     >   "VM_BIND" engine,
     >   >> there is a disconnect from the Vulkan 
specification.

     >   >>
     >   >> In Vulkan VM_BIND operations are 
serialized but

  per engine.
     >   >>
     >   >> So you could have something like this :
     >   >>
     >   >> VM_BIND (engine=rcs0, in_fence=fence1,
  out_fence=fence2)
     >   >>
     >   >> VM_BIND (engine=ccs0, in_fence=fence3,
  out_fence=fence4)
     >   >>
     >   >>
     >   >> fence1 is not signaled
     >   >>
     >   >> fence3 is signaled
     >   >>
     >   

Re: [PATCH] iosys-map: Add word-sized reads

2022-06-10 Thread Lucas De Marchi

On Fri, Jun 10, 2022 at 09:20:18AM +0200, Christian König wrote:

Am 10.06.22 um 01:20 schrieb Lucas De Marchi:

Instead of always falling back to memcpy_fromio() for any size, prefer
using read{b,w,l}(). When reading struct members it's common to read
individual integer variables individually. Going through memcpy_fromio()
for each of them poses a high penalty.

Employ a similar trick as __seqprop() by using _Generic() to generate
only the specific call based on a type-compatible variable.

For a pariticular i915 workload producing GPU context switches,
__get_engine_usage_record() is particularly hot since the engine usage
is read from device local memory with dgfx, possibly multiple times
since it's racy. Test execution time for this test shows a ~12.5%
improvement with DG2:

Before:
nrepeats = 1000; min = 7.63243e+06; max = 1.01817e+07;
median = 9.52548e+06; var = 526149;
After:
nrepeats = 1000; min = 7.03402e+06; max = 8.8832e+06;
median = 8.33955e+06; var = 333113;

Other things attempted that didn't prove very useful:
1) Change the _Generic() on x86 to just dereference the memory address
2) Change __get_engine_usage_record() to do just 1 read per loop,
   comparing with the previous value read
3) Change __get_engine_usage_record() to access the fields directly as it
   was before the conversion to iosys-map

(3) did gave a small improvement (~3%), but doesn't seem to scale well
to other similar cases in the driver.

Additional test by Chris Wilson using gem_create from igt with some
changes to track object creation time. This happens to accidentaly
stress this code path:

Pre iosys_map conversion of engine busyness:
lmem0: Creating262144 4KiB objects took 59274.2ms

Unpatched:
lmem0: Creating262144 4KiB objects took 108830.2ms

With readl (this patch):
lmem0: Creating262144 4KiB objects took 61348.6ms

s/readl/READ_ONCE/
lmem0: Creating262144 4KiB objects took 61333.2ms

So we do take a little bit more time than before the conversion, but
that is due to other factors: bringing the READ_ONCE back would be as
good as just doing this conversion.

Signed-off-by: Lucas De Marchi 
---

If this is acceptable we should probably add the write counterpart, too.
Sending here only the read for now since this fixes the issue we are
seeing and to gather feedback.


As far as I can see looks sane to me, but the kernel test robot tears 
the patch apart.


Probably just a typo somewhere in the 32bit handling.


oh, yeah... after cleaning it up I renamed 
s/__iosys_map_u64_case/__iosys_map_rd_io_u64_case/
to prepare for adding the write case and forgot the other side of the
ifdef.




Apart from that looks good to me.


thanks
Lucas De Marchi



Regards,
Christian.



 include/linux/iosys-map.h | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index e69a002d5aa4..4ae3e459419e 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -333,6 +333,20 @@ static inline void iosys_map_memset(struct iosys_map *dst, 
size_t offset,
memset(dst->vaddr + offset, value, len);
 }
+#ifdef CONFIG_64BIT
+#define __iosys_map_rd_io_u64_case(val_, vaddr_iomem_) \
+   u64: val_ = readq(vaddr_iomem_),
+#else
+#define __iosys_map_u64_case(val_, vaddr_iomem_)
+#endif
+
+#define __iosys_map_rd_io(val__, vaddr_iomem__, type__) _Generic(val__,
\
+   u8: val__ = readb(vaddr_iomem__),   \
+   u16: val__ = readw(vaddr_iomem__),  \
+   u32: val__ = readl(vaddr_iomem__),  \
+   __iosys_map_rd_io_u64_case(val__, vaddr_iomem__)\
+   default: memcpy_fromio(&(val__), vaddr_iomem__, sizeof(val__)))
+
 /**
  * iosys_map_rd - Read a C-type value from the iosys_map
  *
@@ -346,10 +360,14 @@ static inline void iosys_map_memset(struct iosys_map 
*dst, size_t offset,
  * Returns:
  * The value read from the mapping.
  */
-#define iosys_map_rd(map__, offset__, type__) ({   \
-   type__ val; \
-   iosys_map_memcpy_from(, map__, offset__, sizeof(val));  \
-   val;\
+#define iosys_map_rd(map__, offset__, type__) ({   
\
+   type__ val; 
\
+   if ((map__)->is_iomem) { \
+   __iosys_map_rd_io(val, (map__)->vaddr_iomem + offset__, 
type__);\
+   } else {
\
+   memcpy(, (map__)->vaddr + offset__, sizeof(val));   
 \
+   }   
\
+  

[PATCH] drm/msm/gem: Drop early returns in close/purge vma

2022-06-10 Thread Rob Clark
From: Rob Clark 

Keep the warn, but drop the early return.  If we do manage to hit this
sort of issue, skipping the cleanup just makes things worse (dangling
drm_mm_nodes when the msm_gem_vma is freed, etc).  Whereas the worst
that happens if we tear down a mapping the GPU is accessing is that we
get GPU iova faults, but otherwise the world keeps spinning.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_gem_vma.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
b/drivers/gpu/drm/msm/msm_gem_vma.c
index 3c1dc9241831..c471aebcdbab 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -62,8 +62,7 @@ void msm_gem_purge_vma(struct msm_gem_address_space *aspace,
unsigned size = vma->node.size;
 
/* Print a message if we try to purge a vma in use */
-   if (GEM_WARN_ON(msm_gem_vma_inuse(vma)))
-   return;
+   GEM_WARN_ON(msm_gem_vma_inuse(vma));
 
/* Don't do anything if the memory isn't mapped */
if (!vma->mapped)
@@ -128,8 +127,7 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace,
 void msm_gem_close_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma)
 {
-   if (GEM_WARN_ON(msm_gem_vma_inuse(vma) || vma->mapped))
-   return;
+   GEM_WARN_ON(msm_gem_vma_inuse(vma) || vma->mapped);
 
spin_lock(>lock);
if (vma->iova)
-- 
2.36.1



Re: [PATCH 2/3] drm/i915: Update i915 uapi documentation

2022-06-10 Thread Niranjana Vishwanathapura

On Fri, Jun 10, 2022 at 12:01:24PM +0100, Matthew Auld wrote:

On 10/06/2022 08:07, Niranjana Vishwanathapura wrote:

Add some missing i915 upai documentation which the new
i915 VM_BIND feature documentation will be refer to.

Signed-off-by: Niranjana Vishwanathapura 

Reviewed-by: Matthew Auld 

This one looks to be standalone. If no objections should we go ahead 
and merge this one?


Yah, I agree.

Niranjana




---
 include/uapi/drm/i915_drm.h | 203 
 1 file changed, 158 insertions(+), 45 deletions(-)

diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index de49b68b4fc8..9cf3bf47c7f2 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -751,14 +751,27 @@ typedef struct drm_i915_irq_wait {
 /* Must be kept compact -- no holes and well documented */
-typedef struct drm_i915_getparam {
+/**
+ * struct drm_i915_getparam - Driver parameter query structure.
+ */
+struct drm_i915_getparam {
+   /** @param: Driver parameter to query. */
__s32 param;
-   /*
+
+   /**
+* @value: Address of memory where queried value should be put.
+*
 * WARNING: Using pointers instead of fixed-size u64 means we need to 
write
 * compat32 code. Don't repeat this mistake.
 */
int __user *value;
-} drm_i915_getparam_t;
+};
+
+/**
+ * typedef drm_i915_getparam_t - Driver parameter query structure.
+ * See struct drm_i915_getparam.
+ */
+typedef struct drm_i915_getparam drm_i915_getparam_t;
 /* Ioctl to set kernel params:
  */
@@ -1239,76 +1252,119 @@ struct drm_i915_gem_exec_object2 {
__u64 rsvd2;
 };
+/**
+ * struct drm_i915_gem_exec_fence - An input or output fence for the execbuf
+ * ioctl.
+ *
+ * The request will wait for input fence to signal before submission.
+ *
+ * The returned output fence will be signaled after the completion of the
+ * request.
+ */
 struct drm_i915_gem_exec_fence {
-   /**
-* User's handle for a drm_syncobj to wait on or signal.
-*/
+   /** @handle: User's handle for a drm_syncobj to wait on or signal. */
__u32 handle;
+   /**
+* @flags: Supported flags are:
+*
+* I915_EXEC_FENCE_WAIT:
+* Wait for the input fence before request submission.
+*
+* I915_EXEC_FENCE_SIGNAL:
+* Return request completion fence as output
+*/
+   __u32 flags;
 #define I915_EXEC_FENCE_WAIT(1<<0)
 #define I915_EXEC_FENCE_SIGNAL  (1<<1)
 #define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1))
-   __u32 flags;
 };
-/*
- * See drm_i915_gem_execbuffer_ext_timeline_fences.
- */
-#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
-
-/*
+/**
+ * struct drm_i915_gem_execbuffer_ext_timeline_fences - Timeline fences
+ * for execbuf ioctl.
+ *
  * This structure describes an array of drm_syncobj and associated points for
  * timeline variants of drm_syncobj. It is invalid to append this structure to
  * the execbuf if I915_EXEC_FENCE_ARRAY is set.
  */
 struct drm_i915_gem_execbuffer_ext_timeline_fences {
+#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
+   /** @base: Extension link. See struct i915_user_extension. */
struct i915_user_extension base;
/**
-* Number of element in the handles_ptr & value_ptr arrays.
+* @fence_count: Number of elements in the @handles_ptr & @value_ptr
+* arrays.
 */
__u64 fence_count;
/**
-* Pointer to an array of struct drm_i915_gem_exec_fence of length
-* fence_count.
+* @handles_ptr: Pointer to an array of struct drm_i915_gem_exec_fence
+* of length @fence_count.
 */
__u64 handles_ptr;
/**
-* Pointer to an array of u64 values of length fence_count. Values
-* must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
-* drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
+* @values_ptr: Pointer to an array of u64 values of length
+* @fence_count.
+* Values must be 0 for a binary drm_syncobj. A Value of 0 for a
+* timeline drm_syncobj is invalid as it turns a drm_syncobj into a
+* binary one.
 */
__u64 values_ptr;
 };
+/**
+ * struct drm_i915_gem_execbuffer2 - Structure for DRM_I915_GEM_EXECBUFFER2
+ * ioctl.
+ */
 struct drm_i915_gem_execbuffer2 {
-   /**
-* List of gem_exec_object2 structs
-*/
+   /** @buffers_ptr: Pointer to a list of gem_exec_object2 structs */
__u64 buffers_ptr;
+
+   /** @buffer_count: Number of elements in @buffers_ptr array */
__u32 buffer_count;
-   /** Offset in the batchbuffer to start execution from. */
+   /**
+* @batch_start_offset: Offset in the batchbuffer to start execution
+* from.
+*/
__u32 batch_start_offset;
-   /** Bytes used in batchbuffer from 

Re: [PATCH 3/3] drm/doc/rfc: VM_BIND uapi definition

2022-06-10 Thread Niranjana Vishwanathapura

On Fri, Jun 10, 2022 at 01:56:58AM -0700, Matthew Brost wrote:

On Fri, Jun 10, 2022 at 01:53:40AM -0700, Matthew Brost wrote:

On Fri, Jun 10, 2022 at 12:07:11AM -0700, Niranjana Vishwanathapura wrote:
> VM_BIND and related uapi definitions
>
> Signed-off-by: Niranjana Vishwanathapura 
> ---
>  Documentation/gpu/rfc/i915_vm_bind.h | 490 +++
>  1 file changed, 490 insertions(+)
>  create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h
>
> diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
b/Documentation/gpu/rfc/i915_vm_bind.h
> new file mode 100644
> index ..9fc854969cfb
> --- /dev/null
> +++ b/Documentation/gpu/rfc/i915_vm_bind.h
> @@ -0,0 +1,490 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2022 Intel Corporation
> + */
> +
> +/**
> + * DOC: I915_PARAM_HAS_VM_BIND
> + *
> + * VM_BIND feature availability.
> + * See typedef drm_i915_getparam_t param.
> + * bit[0]: If set, VM_BIND is supported, otherwise not.
> + * bits[8-15]: VM_BIND implementation version.
> + * version 0 will not have VM_BIND/UNBIND timeline fence array support.
> + */
> +#define I915_PARAM_HAS_VM_BIND57
> +
> +/**
> + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
> + *
> + * Flag to opt-in for VM_BIND mode of binding during VM creation.
> + * See struct drm_i915_gem_vm_control flags.
> + *
> + * The older execbuf2 ioctl will not support VM_BIND mode of operation.
> + * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any
> + * execlist (See struct drm_i915_gem_execbuffer3 for more details).
> + *
> + */
> +#define I915_VM_CREATE_FLAGS_USE_VM_BIND  (1 << 0)
> +
> +/**
> + * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING
> + *
> + * Flag to declare context as long running.
> + * See struct drm_i915_gem_context_create_ext flags.
> + *
> + * Usage of dma-fence expects that they complete in reasonable amount of 
time.
> + * Compute on the other hand can be long running. Hence it is not appropriate
> + * for compute contexts to export request completion dma-fence to user.
> + * The dma-fence usage will be limited to in-kernel consumption only.
> + * Compute contexts need to use user/memory fence.
> + *
> + * So, long running contexts do not support output fences. Hence,
> + * I915_EXEC_FENCE_SIGNAL (See _i915_gem_exec_fence.flags) is expected
> + * to be not used. DRM_I915_GEM_WAIT ioctl call is also not supported for
> + * objects mapped to long running contexts.
> + */
> +#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING   (1u << 2)
> +
> +/* VM_BIND related ioctls */
> +#define DRM_I915_GEM_VM_BIND  0x3d
> +#define DRM_I915_GEM_VM_UNBIND0x3e
> +#define DRM_I915_GEM_EXECBUFFER3  0x3f
> +#define DRM_I915_GEM_WAIT_USER_FENCE  0x40
> +
> +#define DRM_IOCTL_I915_GEM_VM_BINDDRM_IOWR(DRM_COMMAND_BASE 
+ DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
> +#define DRM_IOCTL_I915_GEM_VM_UNBIND  DRM_IOWR(DRM_COMMAND_BASE 
+ DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
> +#define DRM_IOCTL_I915_GEM_EXECBUFFER3DRM_IOWR(DRM_COMMAND_BASE 
+ DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3)
> +#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCEDRM_IOWR(DRM_COMMAND_BASE 
+ DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence)
> +
> +/**
> + * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
> + *
> + * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU
> + * virtual address (VA) range to the section of an object that should be 
bound
> + * in the device page table of the specified address space (VM).
> + * The VA range specified must be unique (ie., not currently bound) and can
> + * be mapped to whole object or a section of the object (partial binding).
> + * Multiple VA mappings can be created to the same section of the object
> + * (aliasing).
> + *
> + * The @queue_idx specifies the queue to use for binding. Same queue can be
> + * used for both VM_BIND and VM_UNBIND calls. All submitted bind and unbind
> + * operations in a queue are performed in the order of submission.
> + *
> + * The @start, @offset and @length should be 4K page aligned. However the DG2
> + * and XEHPSDV has 64K page size for device local-memory and has compact page
> + * table. On those platforms, for binding device local-memory objects, the
> + * @start should be 2M aligned, @offset and @length should be 64K aligned.
> + * Also, on those platforms, it is not allowed to bind an device local-memory
> + * object and a system memory object in a single 2M section of VA range.
> + */
> +struct drm_i915_gem_vm_bind {
> +  /** @vm_id: VM (address space) id to bind */
> +  __u32 vm_id;
> +
> +  /** @queue_idx: Index of queue for binding */
> +  __u32 queue_idx;
> +
> +  /** @rsvd: Reserved, MBZ */
> +  __u32 rsvd;
> +
> +  /** @handle: Object handle */
> +  __u32 handle;
> +
> +  /** @start: Virtual Address start to bind */
> +  __u64 start;
> +
> +  /** @offset: Offset in object 

Re: [Intel-gfx] [PATCH 3/3] drm/doc/rfc: VM_BIND uapi definition

2022-06-10 Thread Niranjana Vishwanathapura

On Fri, Jun 10, 2022 at 05:48:39PM +0300, Lionel Landwerlin wrote:

On 10/06/2022 13:37, Tvrtko Ursulin wrote:


On 10/06/2022 08:07, Niranjana Vishwanathapura wrote:

VM_BIND and related uapi definitions

Signed-off-by: Niranjana Vishwanathapura 


---
  Documentation/gpu/rfc/i915_vm_bind.h | 490 +++
  1 file changed, 490 insertions(+)
  create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h

diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
b/Documentation/gpu/rfc/i915_vm_bind.h

new file mode 100644
index ..9fc854969cfb
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_vm_bind.h
@@ -0,0 +1,490 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+/**
+ * DOC: I915_PARAM_HAS_VM_BIND
+ *
+ * VM_BIND feature availability.
+ * See typedef drm_i915_getparam_t param.
+ * bit[0]: If set, VM_BIND is supported, otherwise not.
+ * bits[8-15]: VM_BIND implementation version.
+ * version 0 will not have VM_BIND/UNBIND timeline fence array support.
+ */
+#define I915_PARAM_HAS_VM_BIND    57
+
+/**
+ * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
+ *
+ * Flag to opt-in for VM_BIND mode of binding during VM creation.
+ * See struct drm_i915_gem_vm_control flags.
+ *
+ * The older execbuf2 ioctl will not support VM_BIND mode of operation.
+ * For VM_BIND mode, we have new execbuf3 ioctl which will not 
accept any

+ * execlist (See struct drm_i915_gem_execbuffer3 for more details).
+ *
+ */
+#define I915_VM_CREATE_FLAGS_USE_VM_BIND    (1 << 0)
+
+/**
+ * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING
+ *
+ * Flag to declare context as long running.
+ * See struct drm_i915_gem_context_create_ext flags.
+ *
+ * Usage of dma-fence expects that they complete in reasonable 
amount of time.
+ * Compute on the other hand can be long running. Hence it is not 
appropriate

+ * for compute contexts to export request completion dma-fence to user.
+ * The dma-fence usage will be limited to in-kernel consumption only.
+ * Compute contexts need to use user/memory fence.
+ *
+ * So, long running contexts do not support output fences. Hence,
+ * I915_EXEC_FENCE_SIGNAL (See _i915_gem_exec_fence.flags) is 
expected
+ * to be not used. DRM_I915_GEM_WAIT ioctl call is also not 
supported for

+ * objects mapped to long running contexts.
+ */
+#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING   (1u << 2)
+
+/* VM_BIND related ioctls */
+#define DRM_I915_GEM_VM_BIND    0x3d
+#define DRM_I915_GEM_VM_UNBIND    0x3e
+#define DRM_I915_GEM_EXECBUFFER3    0x3f
+#define DRM_I915_GEM_WAIT_USER_FENCE    0x40
+
+#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE 
+ DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3)
+#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE 
DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT_USER_FENCE, struct 
drm_i915_gem_wait_user_fence)

+
+/**
+ * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
+ *
+ * This structure is passed to VM_BIND ioctl and specifies the 
mapping of GPU
+ * virtual address (VA) range to the section of an object that 
should be bound

+ * in the device page table of the specified address space (VM).
+ * The VA range specified must be unique (ie., not currently 
bound) and can
+ * be mapped to whole object or a section of the object (partial 
binding).
+ * Multiple VA mappings can be created to the same section of the 
object

+ * (aliasing).
+ *
+ * The @queue_idx specifies the queue to use for binding. Same 
queue can be
+ * used for both VM_BIND and VM_UNBIND calls. All submitted bind 
and unbind

+ * operations in a queue are performed in the order of submission.
+ *
+ * The @start, @offset and @length should be 4K page aligned. 
However the DG2
+ * and XEHPSDV has 64K page size for device local-memory and has 
compact page
+ * table. On those platforms, for binding device local-memory 
objects, the
+ * @start should be 2M aligned, @offset and @length should be 64K 
aligned.
+ * Also, on those platforms, it is not allowed to bind an device 
local-memory
+ * object and a system memory object in a single 2M section of VA 
range.

+ */
+struct drm_i915_gem_vm_bind {
+    /** @vm_id: VM (address space) id to bind */
+    __u32 vm_id;
+
+    /** @queue_idx: Index of queue for binding */
+    __u32 queue_idx;


I have a question here to which I did not find an answer by browsing 
the old threads.


Queue index appears to be an implicit synchronisation mechanism, 
right? Operations on the same index are executed/complete in order 
of ioctl submission?


Do we _have_ to implement this on the kernel side and could just 
allow in/out fence and let userspace deal with it?



It orders operations like in a queue. Which is kind of what happens 
with existing queues/engines.


If I 

[Bug 210301] *ERROR* IB test failed on gfx (-110) on Ryzen 4750u

2022-06-10 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=210301

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

   What|Removed |Added

 CC||alexdeuc...@gmail.com

--- Comment #2 from Alex Deucher (alexdeuc...@gmail.com) ---
Please attach your full dmesg output.  Does iommu=pt help?  Sounds like perhaps
there are sbios bugs around the IOMMU on your platform.  Can you try a newer
sbios?

-- 
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/amdgpu: Fix GTT size reporting in amdgpu_ioctl

2022-06-10 Thread Alex Deucher
Applied.  Thanks!

Alex

On Fri, Jun 10, 2022 at 10:01 AM Michel Dänzer  wrote:
>
> From: Michel Dänzer 
>
> The commit below changed the TTM manager size unit from pages to
> bytes, but failed to adjust the corresponding calculations in
> amdgpu_ioctl.
>
> Fixes: dfa714b88eb0 ("drm/amdgpu: remove GTT accounting v2")
> Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1930
> Bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6642
> Signed-off-by: Michel Dänzer 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 801f6fa692e9..6de63ea6687e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -642,7 +642,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
> struct drm_file *filp)
> atomic64_read(>visible_pin_size),
> vram_gtt.vram_size);
> vram_gtt.gtt_size = ttm_manager_type(>mman.bdev, 
> TTM_PL_TT)->size;
> -   vram_gtt.gtt_size *= PAGE_SIZE;
> vram_gtt.gtt_size -= atomic64_read(>gart_pin_size);
> return copy_to_user(out, _gtt,
> min((size_t)size, sizeof(vram_gtt))) ? 
> -EFAULT : 0;
> @@ -675,7 +674,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
> struct drm_file *filp)
> mem.cpu_accessible_vram.usable_heap_size * 3 / 4;
>
> mem.gtt.total_heap_size = gtt_man->size;
> -   mem.gtt.total_heap_size *= PAGE_SIZE;
> mem.gtt.usable_heap_size = mem.gtt.total_heap_size -
> atomic64_read(>gart_pin_size);
> mem.gtt.heap_usage = ttm_resource_manager_usage(gtt_man);
> --
> 2.36.1
>


[PATCH v7] drm/i915/display: disable HPD workers before display driver unregister

2022-06-10 Thread Andrzej Hajda
Handling HPD during driver removal is pointless, and can cause different
use-after-free/concurrency issues:
1. Setup of deferred fbdev after fbdev unregistration.
2. Access to DP-AUX after DP-AUX removal.

Below stacktraces of both cases observed on CI:

[272.634530] general protection fault, probably for non-canonical address 
0x6b6b6b6b6b6b6b6b:  [#1] PREEMPT SMP NOPTI
[272.634536] CPU: 0 PID: 6030 Comm: i915_selftest Tainted: G U
5.18.0-rc5-CI_DRM_11603-g12dccf4f5eef+ #1
[272.634541] Hardware name: Intel Corporation Raptor Lake Client Platform/RPL-S 
ADP-S DDR5 UDIMM CRB, BIOS RPLSFWI1.R00.2397.A01.2109300731 09/30/2021
[272.634545] RIP: 0010:fb_do_apertures_overlap.part.14+0x26/0x60
...
[272.634582] Call Trace:
[272.634583]  
[272.634585]  do_remove_conflicting_framebuffers+0x59/0xa0
[272.634589]  remove_conflicting_framebuffers+0x2d/0xc0
[272.634592]  remove_conflicting_pci_framebuffers+0xc8/0x110
[272.634595]  drm_aperture_remove_conflicting_pci_framebuffers+0x52/0x70
[272.634604]  i915_driver_probe+0x63a/0xdd0 [i915]

[283.405824] cpu_latency_qos_update_request called for unknown object
[283.405866] WARNING: CPU: 2 PID: 240 at kernel/power/qos.c:296 
cpu_latency_qos_update_request+0x2d/0x100
[283.405912] CPU: 2 PID: 240 Comm: kworker/u64:9 Not tainted 
5.18.0-rc6-Patchwork_103738v3-g1672d1c43e43+ #1
[283.405915] Hardware name: Intel Corporation Raptor Lake Client Platform/RPL-S 
ADP-S DDR5 UDIMM CRB, BIOS RPLSFWI1.R00.2397.A01.2109300731 09/30/2021
[283.405916] Workqueue: i915-dp i915_digport_work_func [i915]
[283.406020] RIP: 0010:cpu_latency_qos_update_request+0x2d/0x100
...
[283.406040] Call Trace:
[283.406041]  
[283.406044]  intel_dp_aux_xfer+0x60e/0x8e0 [i915]
[283.406131]  ? finish_swait+0x80/0x80
[283.406139]  intel_dp_aux_transfer+0xc5/0x2b0 [i915]
[283.406218]  drm_dp_dpcd_access+0x79/0x130 [drm_display_helper]
[283.406227]  drm_dp_dpcd_read+0xe2/0xf0 [drm_display_helper]
[283.406233]  intel_dp_hpd_pulse+0x134/0x570 [i915]
[283.406308]  ? __down_killable+0x70/0x140
[283.406313]  i915_digport_work_func+0xba/0x150 [i915]

Signed-off-by: Andrzej Hajda 
---
Hi All,

I am not sure about changes in shutdown path, any comments welcome.
I suspect suspend path have also some common bits, but I am little
bit afraid of touching it.

Changes:
v1 - v6:
- chasing the bug appearing only on public CI.
v7:
- shutdown path adjusted (suggested by Jani)

Regards
Andrzej
---
 drivers/gpu/drm/i915/display/intel_display.c | 11 ---
 drivers/gpu/drm/i915/i915_driver.c   |  5 ++---
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 186b37925d23f2..f9952ee8289fb2 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -10490,13 +10490,6 @@ void intel_modeset_driver_remove_noirq(struct 
drm_i915_private *i915)
 */
intel_hpd_poll_fini(i915);
 
-   /*
-* MST topology needs to be suspended so we don't have any calls to
-* fbdev after it's finalized. MST will be destroyed later as part of
-* drm_mode_config_cleanup()
-*/
-   intel_dp_mst_suspend(i915);
-
/* poll work can call into fbdev, hence clean that up afterwards */
intel_fbdev_fini(i915);
 
@@ -10588,6 +10581,10 @@ void intel_display_driver_unregister(struct 
drm_i915_private *i915)
if (!HAS_DISPLAY(i915))
return;
 
+   intel_dp_mst_suspend(i915);
+   intel_hpd_cancel_work(i915);
+   drm_kms_helper_poll_disable(>drm);
+
intel_fbdev_unregister(i915);
intel_audio_deinit(i915);
 
diff --git a/drivers/gpu/drm/i915/i915_driver.c 
b/drivers/gpu/drm/i915/i915_driver.c
index d26dcca7e654aa..82cdccf072e2bc 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -1070,15 +1070,14 @@ void i915_driver_shutdown(struct drm_i915_private *i915)
i915_gem_suspend(i915);
 
if (HAS_DISPLAY(i915)) {
+   intel_dp_mst_suspend(i915);
+   intel_hpd_cancel_work(i915);
drm_kms_helper_poll_disable(>drm);
 
drm_atomic_helper_shutdown(>drm);
}
 
-   intel_dp_mst_suspend(i915);
-
intel_runtime_pm_disable_interrupts(i915);
-   intel_hpd_cancel_work(i915);
 
intel_suspend_encoders(i915);
intel_shutdown_encoders(i915);
-- 
2.25.1



Re: [PATCH v3] drm/msm: Avoid unclocked GMU register access in 6xx gpu_busy

2022-06-10 Thread Rob Clark
On Thu, Jun 9, 2022 at 5:10 PM Douglas Anderson  wrote:
>
> From testing on sc7180-trogdor devices, reading the GMU registers
> needs the GMU clocks to be enabled. Those clocks get turned on in
> a6xx_gmu_resume(). Confusingly enough, that function is called as a
> result of the runtime_pm of the GPU "struct device", not the GMU
> "struct device". Unfortunately the current a6xx_gpu_busy() grabs a
> reference to the GMU's "struct device".
>
> The fact that we were grabbing the wrong reference was easily seen to
> cause crashes that happen if we change the GPU's pm_runtime usage to
> not use autosuspend. It's also believed to cause some long tail GPU
> crashes even with autosuspend.
>
> We could look at changing it so that we do pm_runtime_get_if_in_use()
> on the GPU's "struct device", but then we run into a different
> problem. pm_runtime_get_if_in_use() will return 0 for the GPU's
> "struct device" the whole time when we're in the "autosuspend
> delay". That is, when we drop the last reference to the GPU but we're
> waiting a period before actually suspending then we'll think the GPU
> is off. One reason that's bad is that if the GPU didn't actually turn
> off then the cycle counter doesn't lose state and that throws off all
> of our calculations.
>
> Let's change the code to keep track of the suspend state of
> devfreq. msm_devfreq_suspend() is always called before we actually
> suspend the GPU and msm_devfreq_resume() after we resume it. This
> means we can use the suspended state to know if we're powered or not.
>
> NOTE: one might wonder when exactly our status function is called when
> devfreq is supposed to be disabled. The stack crawl I captured was:
>   msm_devfreq_get_dev_status
>   devfreq_simple_ondemand_func
>   devfreq_update_target
>   qos_notifier_call
>   qos_max_notifier_call
>   blocking_notifier_call_chain
>   pm_qos_update_target
>   freq_qos_apply
>   apply_constraint
>   __dev_pm_qos_update_request
>   dev_pm_qos_update_request
>   msm_devfreq_idle_work
>
> Fixes: eadf79286a4b ("drm/msm: Check for powered down HW in the devfreq 
> callbacks")
> Signed-off-by: Douglas Anderson 
> ---
>
> Changes in v3:
> - Totally rewrote to not use the pm_runtime functions.
> - Moved the code to be common for all adreno GPUs.
>
> Changes in v2:
> - Move the set_freq runtime pm grab to the GPU file.
> - Use <= for the pm_runtime test, not ==.
>
>  drivers/gpu/drm/msm/adreno/a5xx_gpu.c |  8 --
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 13 -
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 12 +++--
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.h |  3 ++-
>  drivers/gpu/drm/msm/msm_gpu.h |  9 ++-
>  drivers/gpu/drm/msm/msm_gpu_devfreq.c | 39 +--
>  6 files changed, 51 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> index c424e9a37669..3dcec7acb384 100644
> --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> @@ -1666,18 +1666,10 @@ static u64 a5xx_gpu_busy(struct msm_gpu *gpu, 
> unsigned long *out_sample_rate)
>  {
> u64 busy_cycles;
>
> -   /* Only read the gpu busy if the hardware is already active */
> -   if (pm_runtime_get_if_in_use(>pdev->dev) == 0) {
> -   *out_sample_rate = 1;
> -   return 0;
> -   }
> -
> busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
> REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
> *out_sample_rate = clk_get_rate(gpu->core_clk);
>
> -   pm_runtime_put(>pdev->dev);
> -
> return busy_cycles;
>  }
>
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> index 9f76f5b15759..dc715d88ff21 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> @@ -102,7 +102,8 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
> A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
>  }
>
> -void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
> +void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,
> +  bool suspended)
>  {
> struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
> struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
> @@ -127,15 +128,16 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct 
> dev_pm_opp *opp)
>
> /*
>  * This can get called from devfreq while the hardware is idle. Don't
> -* bring up the power if it isn't already active
> +* bring up the power if it isn't already active. All we're doing here
> +* is updating the frequency so that when we come back online we're at
> +* the right rate.
>  */
> -   if (pm_runtime_get_if_in_use(gmu->dev) == 0)
> +   if (suspended)
> return;
>
> if (!gmu->legacy) {
> a6xx_hfi_set_freq(gmu, perf_index);
> 

How to convert drivers/gpu/drm/i915/ to use local workqueue?

2022-06-10 Thread Tetsuo Handa
Hello.

Like commit c4f135d643823a86 ("workqueue: Wrap flush_workqueue() using
a macro") explains, we are removing flush_scheduled_work() calls. And now

  drivers/gpu/drm/i915/display/intel_display.c
  drivers/gpu/drm/i915/gt/selftest_execlists.c

are the last flush_scheduled_work() callers which have no patch proposed.
I want to make a patch like
https://lkml.kernel.org/r/e9b95132-89cd-5cfc-1a09-966393c5e...@i-love.sakura.ne.jp
but I couldn't understand how to interpret drivers/gpu/drm/i915/ part.



There are many schedule_work()/schedule_delayed_work() callers within
drivers/gpu/drm/i915/ directory.

intel_modeset_driver_remove_noirq() in intel_display.c says

/* flush any delayed tasks or pending work */
flush_scheduled_work();

but intel_display.c itself does not call schedule_delayed_work().
Then, does this flush_scheduled_work() mean to wait all 
schedule_work()/schedule_delayed_work()
calls inside drivers/gpu/drm/i915/ directory?

wait_for_reset() in selftest_execlists.c says

flush_scheduled_work();

but selftest_execlists.c itself does not call 
schedule_work()/schedule_delayed_work().
Then, does this flush_scheduled_work() mean to wait all 
schedule_work()/schedule_delayed_work()
calls inside drivers/gpu/drm/i915/ directory, by sharing a WQ created for
intel_modeset_driver_remove_noirq() ?


Re: [Intel-gfx] [PATCH 3/3] drm/doc/rfc: VM_BIND uapi definition

2022-06-10 Thread Lionel Landwerlin

On 10/06/2022 13:37, Tvrtko Ursulin wrote:


On 10/06/2022 08:07, Niranjana Vishwanathapura wrote:

VM_BIND and related uapi definitions

Signed-off-by: Niranjana Vishwanathapura 


---
  Documentation/gpu/rfc/i915_vm_bind.h | 490 +++
  1 file changed, 490 insertions(+)
  create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h

diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
b/Documentation/gpu/rfc/i915_vm_bind.h

new file mode 100644
index ..9fc854969cfb
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_vm_bind.h
@@ -0,0 +1,490 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+/**
+ * DOC: I915_PARAM_HAS_VM_BIND
+ *
+ * VM_BIND feature availability.
+ * See typedef drm_i915_getparam_t param.
+ * bit[0]: If set, VM_BIND is supported, otherwise not.
+ * bits[8-15]: VM_BIND implementation version.
+ * version 0 will not have VM_BIND/UNBIND timeline fence array support.
+ */
+#define I915_PARAM_HAS_VM_BIND    57
+
+/**
+ * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
+ *
+ * Flag to opt-in for VM_BIND mode of binding during VM creation.
+ * See struct drm_i915_gem_vm_control flags.
+ *
+ * The older execbuf2 ioctl will not support VM_BIND mode of operation.
+ * For VM_BIND mode, we have new execbuf3 ioctl which will not 
accept any

+ * execlist (See struct drm_i915_gem_execbuffer3 for more details).
+ *
+ */
+#define I915_VM_CREATE_FLAGS_USE_VM_BIND    (1 << 0)
+
+/**
+ * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING
+ *
+ * Flag to declare context as long running.
+ * See struct drm_i915_gem_context_create_ext flags.
+ *
+ * Usage of dma-fence expects that they complete in reasonable 
amount of time.
+ * Compute on the other hand can be long running. Hence it is not 
appropriate

+ * for compute contexts to export request completion dma-fence to user.
+ * The dma-fence usage will be limited to in-kernel consumption only.
+ * Compute contexts need to use user/memory fence.
+ *
+ * So, long running contexts do not support output fences. Hence,
+ * I915_EXEC_FENCE_SIGNAL (See _i915_gem_exec_fence.flags) is 
expected
+ * to be not used. DRM_I915_GEM_WAIT ioctl call is also not 
supported for

+ * objects mapped to long running contexts.
+ */
+#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING   (1u << 2)
+
+/* VM_BIND related ioctls */
+#define DRM_I915_GEM_VM_BIND    0x3d
+#define DRM_I915_GEM_VM_UNBIND    0x3e
+#define DRM_I915_GEM_EXECBUFFER3    0x3f
+#define DRM_I915_GEM_WAIT_USER_FENCE    0x40
+
+#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3)
+#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE 
+ DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence)

+
+/**
+ * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
+ *
+ * This structure is passed to VM_BIND ioctl and specifies the 
mapping of GPU
+ * virtual address (VA) range to the section of an object that 
should be bound

+ * in the device page table of the specified address space (VM).
+ * The VA range specified must be unique (ie., not currently bound) 
and can
+ * be mapped to whole object or a section of the object (partial 
binding).
+ * Multiple VA mappings can be created to the same section of the 
object

+ * (aliasing).
+ *
+ * The @queue_idx specifies the queue to use for binding. Same queue 
can be
+ * used for both VM_BIND and VM_UNBIND calls. All submitted bind and 
unbind

+ * operations in a queue are performed in the order of submission.
+ *
+ * The @start, @offset and @length should be 4K page aligned. 
However the DG2
+ * and XEHPSDV has 64K page size for device local-memory and has 
compact page
+ * table. On those platforms, for binding device local-memory 
objects, the
+ * @start should be 2M aligned, @offset and @length should be 64K 
aligned.
+ * Also, on those platforms, it is not allowed to bind an device 
local-memory
+ * object and a system memory object in a single 2M section of VA 
range.

+ */
+struct drm_i915_gem_vm_bind {
+    /** @vm_id: VM (address space) id to bind */
+    __u32 vm_id;
+
+    /** @queue_idx: Index of queue for binding */
+    __u32 queue_idx;


I have a question here to which I did not find an answer by browsing 
the old threads.


Queue index appears to be an implicit synchronisation mechanism, 
right? Operations on the same index are executed/complete in order of 
ioctl submission?


Do we _have_ to implement this on the kernel side and could just allow 
in/out fence and let userspace deal with it?



It orders operations like in a queue. Which is kind of what happens with 
existing queues/engines.


If I understood correctly, it's going to be a kthread + a linked list right?


Re: [PATCH v6 00/22] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers

2022-06-10 Thread Dmitry Osipenko
On 5/27/22 02:50, Dmitry Osipenko wrote:
> Hello,
> 
> This patchset introduces memory shrinker for the VirtIO-GPU DRM driver
> and adds memory purging and eviction support to VirtIO-GPU driver.
> 
> The new dma-buf locking convention is introduced here as well.
> 
> During OOM, the shrinker will release BOs that are marked as "not needed"
> by userspace using the new madvise IOCTL, it will also evict idling BOs
> to SWAP. The userspace in this case is the Mesa VirGL driver, it will mark
> the cached BOs as "not needed", allowing kernel driver to release memory
> of the cached shmem BOs on lowmem situations, preventing OOM kills.
> 
> The Panfrost driver is switched to use generic memory shrinker.
> 
> This patchset includes improvements and fixes for various things that
> I found while was working on the shrinker.
> 
> The Mesa and IGT patches will be kept on hold until this kernel series
> will be approved and merged.
> 
> This patchset was tested using Qemu and crosvm, including both cases of
> IOMMU off/on.
> 
> Mesa: https://gitlab.freedesktop.org/digetx/mesa/-/commits/virgl-madvise
> IGT:  
> https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/virtio-madvise
>   
> https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/panfrost-madvise
> 
> Changelog:
> 
> v6: - Added new VirtIO-related fix patch that previously was sent separately
>   and didn't get much attention:
> 
> drm/gem: Properly annotate WW context on drm_gem_lock_reservations() 
> error
> 
> - Added new patch that fixes mapping of imported dma-bufs for
>   Tegra DRM and other affected drivers. It's also handy to have it
>   for switching to the new dma-buf locking convention scheme:
> 
> drm/gem: Move mapping of imported dma-bufs to drm_gem_mmap_obj()
> 
> - Added new patch that fixes shrinker list corruption for stable Panfrost
>   driver:
> 
> drm/panfrost: Fix shrinker list corruption by madvise IOCTL
> 
> - Added new minor patch-fix for drm-shmem:
> 
> drm/shmem-helper: Add missing vunmap on error
> 
> - Added fixes tag to the "Put mapping ..." patch like was suggested by
>   Steven Price.
> 
> - Added new VirtIO-GPU driver improvement patch:
> 
> drm/virtio: Return proper error codes instead of -1
> 
> - Reworked shrinker patches like was suggested by Daniel Vetter:
> 
> - Introduced the new locking convention for dma-bufs. Tested on
>   VirtIO-GPU, Panfrost, Lima, Tegra and Intel selftests.
> 
> - Dropped separate purge() callback. Now single evict() does
>   everything.
> 
> - Dropped swap_in() callback from drm-shmem objects. DRM drivers
>   now could and should restore only the required mappings.
> 
> - Dropped dynamic counting of evictable pages. This simplifies
>   code in exchange to *potentially* burning more CPU time on OOM.
> 
> v5: - Added new for-stable patch "drm/panfrost: Put mapping instead of
>   shmem obj on panfrost_mmu_map_fault_addr() error" that corrects GEM's
>   refcounting in case of error.
> 
> - The drm_gem_shmem_v[un]map() now takes a separate vmap_lock for
>   imported GEMs to avoid recursive locking of DMA reservations.
>   This addresses v4 comment from Thomas Zimmermann about the potential
>   deadlocking of vmapping.
> 
> - Added ack from Thomas Zimmermann to "drm/shmem-helper: Correct
>   doc-comment of drm_gem_shmem_get_sg_table()" patch.
> 
> - Dropped explicit shmem states from the generic shrinker patch as
>   was requested by Thomas Zimmermann.
> 
> - Improved variable names and comments of the generic shrinker code.
> 
> - Extended drm_gem_shmem_print_info() with the shrinker-state info in
>   the "drm/virtio: Support memory shrinking" patch.
> 
> - Moved evict()/swap_in()/purge() callbacks from drm_gem_object_funcs
>   to drm_gem_shmem_object in the generic shrinker patch, for more
>   consistency.
> 
> - Corrected bisectability of the patches that was broken in v4
>   by accident.
> 
> - The virtio_gpu_plane_prepare_fb() now uses drm_gem_shmem_pin() instead
>   of drm_gem_shmem_set_unpurgeable_and_unevictable() and does it only for
>   shmem BOs in the "drm/virtio: Support memory shrinking" patch.
> 
> - Made more functions private to drm_gem_shmem_helper.c as was requested
>   by Thomas Zimmermann. This minimizes number of the public shmem helpers.
> 
> v4: - Corrected minor W=1 warnings reported by kernel test robot for v3.
> 
> - Renamed DRM_GEM_SHMEM_PAGES_STATE_ACTIVE/INACTIVE to PINNED/UNPINNED,
>   for more clarity.
> 
> v3: - Hardened shrinker's count() with usage of READ_ONCE() since we don't
>   use atomic type for counting and technically compiler is free to
>   re-fetch counter's variable.
> 
> - "Correct drm_gem_shmem_get_sg_table() error handling" now uses
>   PTR_ERR_OR_ZERO(), fixing typo that was 

[PATCH v2] gpu/drm/bridge/cadence: avoid flush_scheduled_work() usage

2022-06-10 Thread Tetsuo Handa
Use local wq in order to avoid flush_scheduled_work() usage.

Signed-off-by: Tetsuo Handa 
---
Changes in v2:
  Replace flush_scheduled_work() with flush_workqueue().

Please see commit c4f135d643823a86 ("workqueue: Wrap flush_workqueue()
using a macro") for background.

This is a blind conversion, and is only compile tested.

 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 32 ---
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  2 ++
 .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c   | 16 +-
 3 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index 67f0f444b4e8..f29c9484d4bb 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -53,6 +53,8 @@
 #include "cdns-mhdp8546-hdcp.h"
 #include "cdns-mhdp8546-j721e.h"
 
+struct workqueue_struct *cadence_mhdp_wq;
+
 static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
 {
int ret, empty;
@@ -2049,7 +2051,7 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge 
*bridge,
 out:
mutex_unlock(>link_mutex);
if (ret < 0)
-   schedule_work(>modeset_retry_work);
+   queue_work(cadence_mhdp_wq, >modeset_retry_work);
 }
 
 static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
@@ -2373,7 +2375,7 @@ static irqreturn_t cdns_mhdp_irq_handler(int irq, void 
*data)
spin_unlock(>start_lock);
 
if (bridge_attached && (sw_ev0 & CDNS_DPTX_HPD)) {
-   schedule_work(>hpd_work);
+   queue_work(cadence_mhdp_wq, >hpd_work);
}
 
if (sw_ev0 & ~CDNS_DPTX_HPD) {
@@ -2413,7 +2415,7 @@ static void cdns_mhdp_hpd_work(struct work_struct *work)
ret = cdns_mhdp_update_link_status(mhdp);
if (mhdp->connector.dev) {
if (ret < 0)
-   schedule_work(>modeset_retry_work);
+   queue_work(cadence_mhdp_wq, >modeset_retry_work);
else
drm_kms_helper_hotplug_event(mhdp->bridge.dev);
} else {
@@ -2603,7 +2605,7 @@ static int cdns_mhdp_remove(struct platform_device *pdev)
pm_runtime_disable(>dev);
 
cancel_work_sync(>modeset_retry_work);
-   flush_scheduled_work();
+   flush_workqueue(cadence_mhdp_wq);
 
clk_disable_unprepare(mhdp->clk);
 
@@ -2632,7 +2634,27 @@ static struct platform_driver mhdp_driver = {
.probe  = cdns_mhdp_probe,
.remove = cdns_mhdp_remove,
 };
-module_platform_driver(mhdp_driver);
+
+static int __init mhdp_init(void)
+{
+   int ret;
+
+   cadence_mhdp_wq = alloc_workqueue("cadence_mhdp_wq", 0, 0);
+   if (!cadence_mhdp_wq)
+   return -ENOMEM;
+   ret = platform_driver_register(_driver);
+   if (ret)
+   destroy_workqueue(cadence_mhdp_wq);
+   return ret;
+}
+module_init(mhdp_init);
+
+static void __exit mhdp_exit(void)
+{
+   platform_driver_unregister(_driver);
+   destroy_workqueue(cadence_mhdp_wq);
+}
+module_exit(mhdp_exit);
 
 MODULE_FIRMWARE(FW_NAME);
 
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
index be510d17..e6c475612480 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
@@ -419,4 +419,6 @@ struct cdns_mhdp_device {
 
 u32 cdns_mhdp_wait_for_sw_event(struct cdns_mhdp_device *mhdp, uint32_t event);
 
+extern struct workqueue_struct *cadence_mhdp_wq;
+
 #endif
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
index 946212a95598..09f9e3d42f11 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
@@ -449,14 +449,14 @@ static int cdns_mhdp_hdcp_check_link(struct 
cdns_mhdp_device *mhdp)
ret = _cdns_mhdp_hdcp_disable(mhdp);
if (ret) {
mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   schedule_work(>hdcp.prop_work);
+   queue_work(cadence_mhdp_wq, >hdcp.prop_work);
goto out;
}
 
ret = _cdns_mhdp_hdcp_enable(mhdp, mhdp->hdcp.hdcp_content_type);
if (ret) {
mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   schedule_work(>hdcp.prop_work);
+   queue_work(cadence_mhdp_wq, >hdcp.prop_work);
}
 out:
mutex_unlock(>hdcp.mutex);
@@ -474,8 +474,8 @@ static void cdns_mhdp_hdcp_check_work(struct work_struct 
*work)
 hdcp);
 
if (!cdns_mhdp_hdcp_check_link(mhdp))
-   schedule_delayed_work(>check_work,
- DRM_HDCP_CHECK_PERIOD_MS);
+   queue_delayed_work(cadence_mhdp_wq, 

Re: [PATCH 2/2] vfio/pci: Remove console drivers

2022-06-10 Thread Alex Williamson
On Fri, 10 Jun 2022 09:03:15 +0200
Thomas Zimmermann  wrote:

> Hi
> 
> Am 09.06.22 um 23:44 schrieb Alex Williamson:
> > On Thu, 9 Jun 2022 15:41:02 -0600
> > Alex Williamson  wrote:
> >   
> >> On Thu, 9 Jun 2022 11:13:22 +0200
> >> Thomas Zimmermann  wrote:  
> >>>
> >>> Please have a look at the attached patch. It moves the aperture helpers
> >>> to a location common to the various possible users (DRM, fbdev, vfio).
> >>> The DRM interfaces remain untouched for now.  The patch should provide
> >>> what you need in vfio and also serve our future use cases for graphics
> >>> drivers. If possible, please create your patch on top of it.  
> >>
> >> Looks good to me, this of course makes the vfio change quite trivial.
> >> One change I'd request:
> >>
> >> diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
> >> index 40c50fa2dd70..7f3c44e1538b 100644
> >> --- a/drivers/video/console/Kconfig
> >> +++ b/drivers/video/console/Kconfig
> >> @@ -10,6 +10,7 @@ config VGA_CONSOLE
> >>depends on !4xx && !PPC_8xx && !SPARC && !M68K && !PARISC &&  !SUPERH 
> >> && \
> >>(!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) 
> >> && \
> >>!ARM64 && !ARC && !MICROBLAZE && !OPENRISC && !S390 && !UML
> >> +  select APERTURE_HELPERS if (DRM || FB || VFIO_PCI)
> >>default y
> >>help
> >>  Saying Y here will allow you to use Linux in text mode through a
> >>
> >> This should be VFIO_PCI_CORE.  Thanks,  
> 
> I attached an updated patch to this email.
> 
> > 
> > Also, whatever tree this lands in, I'd appreciate a topic branch being
> > made available so I can more easily get the vfio change in on the same
> > release.  Thanks,  
> 
> You can add my patch to your series and merge it through vfio. You'd 
> only have to cc dri-devel for the patch's review. I guess it's more 
> important for vfio than DRM. We have no hurry on the DRM side, but v5.20 
> would be nice.

Ok, I didn't realize you were offering the patch for me to post and
merge.  I'll do that.  Thanks!

Alex



[PATCH] gpu/drm/bridge/cadence: avoid flush_scheduled_work() usage

2022-06-10 Thread Tetsuo Handa
Use local wq in order to avoid flush_scheduled_work() usage.

Signed-off-by: Tetsuo Handa 
---
Please see commit c4f135d643823a86 ("workqueue: Wrap flush_workqueue()
using a macro") for background.

This is a blind conversion, and is only compile tested.

 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 30 ---
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  2 ++
 .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c   | 16 +-
 3 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index 67f0f444b4e8..1d7c6af66217 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -53,6 +53,8 @@
 #include "cdns-mhdp8546-hdcp.h"
 #include "cdns-mhdp8546-j721e.h"
 
+struct workqueue_struct *cadence_mhdp_wq;
+
 static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
 {
int ret, empty;
@@ -2049,7 +2051,7 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge 
*bridge,
 out:
mutex_unlock(>link_mutex);
if (ret < 0)
-   schedule_work(>modeset_retry_work);
+   queue_work(cadence_mhdp_wq, >modeset_retry_work);
 }
 
 static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
@@ -2373,7 +2375,7 @@ static irqreturn_t cdns_mhdp_irq_handler(int irq, void 
*data)
spin_unlock(>start_lock);
 
if (bridge_attached && (sw_ev0 & CDNS_DPTX_HPD)) {
-   schedule_work(>hpd_work);
+   queue_work(cadence_mhdp_wq, >hpd_work);
}
 
if (sw_ev0 & ~CDNS_DPTX_HPD) {
@@ -2413,7 +2415,7 @@ static void cdns_mhdp_hpd_work(struct work_struct *work)
ret = cdns_mhdp_update_link_status(mhdp);
if (mhdp->connector.dev) {
if (ret < 0)
-   schedule_work(>modeset_retry_work);
+   queue_work(cadence_mhdp_wq, >modeset_retry_work);
else
drm_kms_helper_hotplug_event(mhdp->bridge.dev);
} else {
@@ -2632,7 +2634,27 @@ static struct platform_driver mhdp_driver = {
.probe  = cdns_mhdp_probe,
.remove = cdns_mhdp_remove,
 };
-module_platform_driver(mhdp_driver);
+
+static int __init mhdp_init(void)
+{
+   int ret;
+
+   cadence_mhdp_wq = alloc_workqueue("cadence_mhdp_wq", 0, 0);
+   if (!cadence_mhdp_wq)
+   return -ENOMEM;
+   ret = platform_driver_register(_driver);
+   if (ret)
+   destroy_workqueue(cadence_mhdp_wq);
+   return ret;
+}
+module_init(mhdp_init);
+
+static void __exit mhdp_exit(void)
+{
+   platform_driver_unregister(_driver);
+   destroy_workqueue(cadence_mhdp_wq);
+}
+module_exit(mhdp_exit);
 
 MODULE_FIRMWARE(FW_NAME);
 
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
index be510d17..e6c475612480 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
@@ -419,4 +419,6 @@ struct cdns_mhdp_device {
 
 u32 cdns_mhdp_wait_for_sw_event(struct cdns_mhdp_device *mhdp, uint32_t event);
 
+extern struct workqueue_struct *cadence_mhdp_wq;
+
 #endif
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
index 946212a95598..09f9e3d42f11 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
@@ -449,14 +449,14 @@ static int cdns_mhdp_hdcp_check_link(struct 
cdns_mhdp_device *mhdp)
ret = _cdns_mhdp_hdcp_disable(mhdp);
if (ret) {
mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   schedule_work(>hdcp.prop_work);
+   queue_work(cadence_mhdp_wq, >hdcp.prop_work);
goto out;
}
 
ret = _cdns_mhdp_hdcp_enable(mhdp, mhdp->hdcp.hdcp_content_type);
if (ret) {
mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   schedule_work(>hdcp.prop_work);
+   queue_work(cadence_mhdp_wq, >hdcp.prop_work);
}
 out:
mutex_unlock(>hdcp.mutex);
@@ -474,8 +474,8 @@ static void cdns_mhdp_hdcp_check_work(struct work_struct 
*work)
 hdcp);
 
if (!cdns_mhdp_hdcp_check_link(mhdp))
-   schedule_delayed_work(>check_work,
- DRM_HDCP_CHECK_PERIOD_MS);
+   queue_delayed_work(cadence_mhdp_wq, >check_work,
+  DRM_HDCP_CHECK_PERIOD_MS);
 }
 
 static void cdns_mhdp_hdcp_prop_work(struct work_struct *work)
@@ -538,9 +538,9 @@ int cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 
content_type)
 
mhdp->hdcp.hdcp_content_type = content_type;
mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-   

Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Zack Rusin
On Fri, 2022-06-10 at 10:59 +0200, Daniel Vetter wrote:
> ⚠ External Email
> 
> On Fri, Jun 10, 2022 at 10:41:05AM +0200, Daniel Vetter wrote:
> > Hi all,
> > 
> > Kinda top post because the thread is sprawling and I think we need a
> > summary/restart. I think there's at least 3 issues here:
> > 
> > - lack of hotspot property support, which means compositors can't really
> >   support hotspot with atomic. Which isn't entirely true, because you
> >   totally can use atomic for the primary planes/crtcs and the legacy
> >   cursor ioctls, but I understand that people might find that a bit silly 
> > :-)
> > 
> >   Anyway this problme is solved by the patch set here, and I think results
> >   in some nice cleanups to boot.
> > 
> > - the fact that cursors for virtual drivers are not planes, but really
> >   special things. Which just breaks the universal plane kms uapi. That
> >   part isn't solved, and I do agree with Simon and Pekka that we really
> >   should solve this before we unleash even more compositors onto the
> >   atomic paths of virtual drivers.
> > 
> >   I think the simplest solution for this is:
> >   1. add a new DRM_PLANE_TYPE_VIRTUAL_CURSOR, and set that for these
> >   special cursor planes on all virtual drivers
> >   2. add the new "I understand virtual cursors planes" setparam, filter
> >   virtual cursor planes for userspace which doesn't set this (like we do
> >   right now if userspace doesn't set the universal plane mode)
> >   3. backport the above patches to all stable kernels
> >   4. make sure the hotspot property is only set on VIRTUAL_CURSOR planes
> >   and nothing else in the rebased patch series
> 
> Simon also mentioned on irc that these special planes must not expose the
> CRTC_X/Y property, since that doesn't really do much at all. Or is our
> understanding of how this all works for commandeered cursors wrong?

Yes, that's the part I don't understand. I don't think I see how the CRTC_X|Y
properties aren't used.

I think the confusion might stem from the fact that it appears that the
hypervisors/hosts are moving that plane, which is not the case. We never move 
the
plane itself, we redirect the mouse focus/movement, that's what's reducing the
latency but don't touch drm internals. I can't speak for every virtualized 
stack,
but what is happening on ours is that we set the image that's on the cursor 
plane as
the cursor on the machine that's running the guest. So when you move the mouse
across the screen as you enter the VM window the cursor plane isn't touched, 
but the
local machines cursor changes to what's inside the cursor plane. When the mouse 
is
clicked the mouse device in the guest generates the event with the proper
coordinates (hence we need the hotspot to route that event correctly). That's 
when
the guest reacts just like it would normally on native if a mouse event was
received.

The actual cursor plane might not be visible while this is happening but even 
when
it's not visible it's still at whatever crtc_x|y the guest thinks it is. 
crtc_x|y
are still only driven by the guests mouse device.

We control the mouse device and visibility of the cursor plane itself based on
what's happening in the system but I don't think that's that different from a 
native
system.

This is easy to see by running the "weston-simple-damage --width=64 
--height=64" if
you click on that window and move the cursor to the very edge of the virtualized
window you'll notice that it's coming out outside of the window, that's because 
it's
the local machines cursor, but if you stop the press the window will jump to
wherever it was because the real guest plane is still at crtc_x|y (and because 
in
weston that window doesn't react to mouse move events like a cursor would it 
never
sets crtc_x|y to the mouse directed coordinates). 

The problem stems from the fact that the cursor plane has something that's not a
cursor and doesn't react to mouse events like a cursor would. So the flag (or 
new
plane) that we'd be adding is simply making user-space give the following 
promise:

"I understand that what's inside the cursor plane needs to react and deal with 
mouse
events like a mouse cursor would, i.e. it should be a mouse cursor"


z


Re: [PATCH] iosys-map: Add word-sized reads

2022-06-10 Thread kernel test robot
Hi Lucas,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm-tip/drm-tip]
[also build test ERROR on linus/master v5.19-rc1 next-20220610]
[cannot apply to tegra-drm/drm/tegra/for-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/intel-lab-lkp/linux/commits/Lucas-De-Marchi/iosys-map-Add-word-sized-reads/20220610-072113
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: i386-defconfig 
(https://download.01.org/0day-ci/archive/20220610/202206102230.ji70o9lr-...@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-3) 11.3.0
reproduce (this is a W=1 build):
# 
https://github.com/intel-lab-lkp/linux/commit/7b9b2d6b8d738fe2857fa1a96f7f3c9d8c11e9cd
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Lucas-De-Marchi/iosys-map-Add-word-sized-reads/20220610-072113
git checkout 7b9b2d6b8d738fe2857fa1a96f7f3c9d8c11e9cd
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

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

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/i915/gt/uc/intel_guc.h:10,
from drivers/gpu/drm/i915/gt/uc/intel_uc.h:9,
from drivers/gpu/drm/i915/gt/intel_gt_types.h:18,
from drivers/gpu/drm/i915/gt/intel_gt.h:10,
from drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c:9:
   drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c: In function 
'intel_guc_ads_print_policy_info':
>> include/linux/iosys-map.h:347:9: error: unknown type name 
>> '__iosys_map_rd_io_u64_case'
 347 | __iosys_map_rd_io_u64_case(val__, vaddr_iomem__) 
   \
 | ^~
   include/linux/iosys-map.h:366:17: note: in expansion of macro 
'__iosys_map_rd_io'
 366 | __iosys_map_rd_io(val, (map__)->vaddr_iomem + 
offset__, type__);\
 | ^
   include/linux/iosys-map.h:452:9: note: in expansion of macro 'iosys_map_rd'
 452 | iosys_map_rd(map__, struct_offset__ + 
offsetof(struct_type__, field__), \
 | ^~~~
   drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c:65:9: note: in expansion of macro 
'iosys_map_rd_field'
  65 | iosys_map_rd_field(&(guc_)->ads_map, 0, struct 
__guc_ads_blob, field_)
 | ^~
   drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c:165:20: note: in expansion of 
macro 'ads_blob_read'
 165 |ads_blob_read(guc, policies.dpc_promote_time));
 |^
>> include/linux/iosys-map.h:366:35: error: expected ')' before 'val'
 366 | __iosys_map_rd_io(val, (map__)->vaddr_iomem + 
offset__, type__);\
 |   ^~~
   include/linux/iosys-map.h:347:36: note: in definition of macro 
'__iosys_map_rd_io'
 347 | __iosys_map_rd_io_u64_case(val__, vaddr_iomem__) 
   \
 |^
   include/linux/iosys-map.h:452:9: note: in expansion of macro 'iosys_map_rd'
 452 | iosys_map_rd(map__, struct_offset__ + 
offsetof(struct_type__, field__), \
 | ^~~~
   drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c:65:9: note: in expansion of macro 
'iosys_map_rd_field'
  65 | iosys_map_rd_field(&(guc_)->ads_map, 0, struct 
__guc_ads_blob, field_)
 | ^~
   drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c:165:20: note: in expansion of 
macro 'ads_blob_read'
 165 |ads_blob_read(guc, policies.dpc_promote_time));
 |^
>> include/linux/iosys-map.h:347:9: error: unknown type name 
>> '__iosys_map_rd_io_u64_case'
 347 | __iosys_map_rd_io_u64_case(val__, vaddr_iomem__) 
   \
 | ^~
   include/linux/iosys-map.h:366:17: note: in expansion of macro 
'__iosys_map_rd_io'
 366 | __iosys_map_rd_io(val, (map__)->vaddr_iomem + 
offset__, type__);\
 | ^
   include/linux/iosys-map.h:452:9: note: in expansion of macro 'iosys_map_rd'
 452 | iosys_map_rd(map__, struct_offset__ + 
offsetof(struct_type__, field__), \
 | ^~~~
   drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c:65:9: note: in expansion of macro 
'iosys_map_rd_field'
  65 | iosys_map_rd_field(&(guc_)->ads_map, 0, struct 
__guc_ads_blob, field_)
 | ^~
   drive

[PATCH] drm/amdgpu: Fix GTT size reporting in amdgpu_ioctl

2022-06-10 Thread Michel Dänzer
From: Michel Dänzer 

The commit below changed the TTM manager size unit from pages to
bytes, but failed to adjust the corresponding calculations in
amdgpu_ioctl.

Fixes: dfa714b88eb0 ("drm/amdgpu: remove GTT accounting v2")
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1930
Bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6642
Signed-off-by: Michel Dänzer 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 801f6fa692e9..6de63ea6687e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -642,7 +642,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
atomic64_read(>visible_pin_size),
vram_gtt.vram_size);
vram_gtt.gtt_size = ttm_manager_type(>mman.bdev, 
TTM_PL_TT)->size;
-   vram_gtt.gtt_size *= PAGE_SIZE;
vram_gtt.gtt_size -= atomic64_read(>gart_pin_size);
return copy_to_user(out, _gtt,
min((size_t)size, sizeof(vram_gtt))) ? 
-EFAULT : 0;
@@ -675,7 +674,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
mem.cpu_accessible_vram.usable_heap_size * 3 / 4;
 
mem.gtt.total_heap_size = gtt_man->size;
-   mem.gtt.total_heap_size *= PAGE_SIZE;
mem.gtt.usable_heap_size = mem.gtt.total_heap_size -
atomic64_read(>gart_pin_size);
mem.gtt.heap_usage = ttm_resource_manager_usage(gtt_man);
-- 
2.36.1



Re: [PATCH v11 01/10] dt-bindings: mediatek, dp: Add Display Port binding

2022-06-10 Thread Rob Herring
On Fri, 10 Jun 2022 18:55:13 +0800, Bo-Chen Chen wrote:
> From: Markus Schneider-Pargmann 
> 
> This controller is present on several mediatek hardware. Currently
> mt8195 and mt8395 have this controller without a functional difference,
> so only one compatible field is added.
> 
> The controller can have two forms, as a normal display port and as an
> embedded display port.
> 
> Signed-off-by: Markus Schneider-Pargmann 
> Signed-off-by: Guillaume Ranquet 
> [Bo-Chen: Fix reviewers' comment]
> Signed-off-by: Bo-Chen Chen 
> ---
>  .../display/mediatek/mediatek,dp.yaml | 101 ++
>  1 file changed, 101 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> 

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

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.example.dtb:
 dp_tx@1c60: max-lanes: b'\x04' is not of type 'object', 'array', 
'boolean', 'null'
From schema: 
/usr/local/lib/python3.10/dist-packages/dtschema/schemas/dt-core.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.example.dtb:
 dp_tx@1c60: max-linkrate: b'\x1f\xa4' is not of type 'object', 'array', 
'boolean', 'null'
From schema: 
/usr/local/lib/python3.10/dist-packages/dtschema/schemas/dt-core.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



[PATCH] drm/gma500: Fix SDVO command debug printing

2022-06-10 Thread Patrik Jakobsson
At some point the DRM printers started adding a newline after each
print. This caused SDVO command debug printing to look weird. Fix this
by using snprintf to print into a buffer which can be printed as a whole
by DRM_DEBUG_KMS(). Code is heavily inspired by i915.

Signed-off-by: Patrik Jakobsson 
---
 drivers/gpu/drm/gma500/psb_intel_sdvo.c | 62 -
 1 file changed, 41 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c 
b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
index a85aace25548..bdced46dd333 100644
--- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -400,26 +400,38 @@ static const struct _sdvo_cmd_name {
 #define IS_SDVOB(reg)  (reg == SDVOB)
 #define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC")
 
-static void psb_intel_sdvo_debug_write(struct psb_intel_sdvo *psb_intel_sdvo, 
u8 cmd,
-  const void *args, int args_len)
+static void psb_intel_sdvo_debug_write(struct psb_intel_sdvo *psb_intel_sdvo,
+  u8 cmd, const void *args, int args_len)
 {
-   int i;
+   struct drm_device *dev = psb_intel_sdvo->base.base.dev;
+   int i, pos = 0;
+   char buffer[73];
+
+#define BUF_PRINT(args...) \
+   pos += snprintf(buffer + pos, max_t(int, sizeof(buffer) - pos, 0), args)
+
+   for (i = 0; i < args_len; i++) {
+   BUF_PRINT("%02X ", ((u8 *)args)[i]);
+   }
+
+   for (; i < 8; i++) {
+   BUF_PRINT("   ");
+   }
 
-   DRM_DEBUG_KMS("%s: W: %02X ",
-   SDVO_NAME(psb_intel_sdvo), cmd);
-   for (i = 0; i < args_len; i++)
-   DRM_DEBUG_KMS("%02X ", ((u8 *)args)[i]);
-   for (; i < 8; i++)
-   DRM_DEBUG_KMS("   ");
for (i = 0; i < ARRAY_SIZE(sdvo_cmd_names); i++) {
if (cmd == sdvo_cmd_names[i].cmd) {
-   DRM_DEBUG_KMS("(%s)", sdvo_cmd_names[i].name);
+   BUF_PRINT("(%s)", sdvo_cmd_names[i].name);
break;
}
}
+
if (i == ARRAY_SIZE(sdvo_cmd_names))
-   DRM_DEBUG_KMS("(%02X)", cmd);
-   DRM_DEBUG_KMS("\n");
+   BUF_PRINT("(%02X)", cmd);
+
+   drm_WARN_ON(dev, pos >= sizeof(buffer) - 1);
+#undef BUF_PRINT
+
+   DRM_DEBUG_KMS("%s: W: %02X %s\n", SDVO_NAME(psb_intel_sdvo), cmd, 
buffer);
 }
 
 static const char *cmd_status_names[] = {
@@ -490,13 +502,13 @@ static bool psb_intel_sdvo_write_cmd(struct 
psb_intel_sdvo *psb_intel_sdvo, u8 c
 }
 
 static bool psb_intel_sdvo_read_response(struct psb_intel_sdvo *psb_intel_sdvo,
-void *response, int response_len)
+void *response, int response_len)
 {
+   struct drm_device *dev = psb_intel_sdvo->base.base.dev;
+   char buffer[73];
+   int i, pos = 0;
u8 retry = 5;
u8 status;
-   int i;
-
-   DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(psb_intel_sdvo));
 
/*
 * The documentation states that all commands will be
@@ -520,10 +532,13 @@ static bool psb_intel_sdvo_read_response(struct 
psb_intel_sdvo *psb_intel_sdvo,
goto log_fail;
}
 
+#define BUF_PRINT(args...) \
+   pos += snprintf(buffer + pos, max_t(int, sizeof(buffer) - pos, 0), args)
+
if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
-   DRM_DEBUG_KMS("(%s)", cmd_status_names[status]);
+   BUF_PRINT("(%s)", cmd_status_names[status]);
else
-   DRM_DEBUG_KMS("(??? %d)", status);
+   BUF_PRINT("(??? %d)", status);
 
if (status != SDVO_CMD_STATUS_SUCCESS)
goto log_fail;
@@ -534,13 +549,18 @@ static bool psb_intel_sdvo_read_response(struct 
psb_intel_sdvo *psb_intel_sdvo,
  SDVO_I2C_RETURN_0 + i,
  &((u8 *)response)[i]))
goto log_fail;
-   DRM_DEBUG_KMS(" %02X", ((u8 *)response)[i]);
+   BUF_PRINT(" %02X", ((u8 *)response)[i]);
}
-   DRM_DEBUG_KMS("\n");
+
+   drm_WARN_ON(dev, pos >= sizeof(buffer) - 1);
+#undef BUF_PRINT
+
+   DRM_DEBUG_KMS("%s: R: %s\n", SDVO_NAME(psb_intel_sdvo), buffer);
return true;
 
 log_fail:
-   DRM_DEBUG_KMS("... failed\n");
+   DRM_DEBUG_KMS("%s: R: ... failed %s\n",
+ SDVO_NAME(psb_intel_sdvo), buffer);
return false;
 }
 
-- 
2.36.1



Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Simon Ser
On Friday, June 10th, 2022 at 14:36, Gerd Hoffmann  wrote:

> Hi,
>
> > > As Pekka mentionned, I'd also like to have a conversation of how far we 
> > > want to
> > > push virtualized driver features. I think KMS support is a good feature 
> > > to have
> > > to spin up a VM and have all of the basics working. However I don't think 
> > > it's
> > > a good idea to try to plumb an ever-growing list of fancy features
> > > (seamless integration of guest windows into the host, HiDPI, 
> > > multi-monitor,
> > > etc) into KMS. You'd just end up re-inventing Wayland or RDP on top of 
> > > KMS.
> > > Instead of re-inventing these, just use RDP or waypipe or X11 forwarding
> > > directly.
>
> > > So I think we need to draw a line somewhere, and decide e.g. that 
> > > virtualized
> > > cursors are fine to add in KMS, but HiDPI is not.
>
>
> What is the problem with HiDPI? qemu generates standard edid blobs,
> there should be no need to special-case virtualized drivers in any way.
>
> What is the problem with multi-monitor? That isn't much different than
> physical multi-monitor either.
>
> One little thing though: On physical hardware you just don't know which
> monitor is left and which is right until the user tells you. In case of
> a virtual multi-monitor setup we know how the two windows for the two
> virtual monitors are arranged on the host and can pass that as hint to
> the guest (not sure whenever that is the purpose of the
> suggested_{x,y} properties).

The problem with suggested_x/y is described here:
https://lore.kernel.org/dri-devel/20220610123629.fgu2em3fto53f...@sirius.home.kraxel.org/T/#m119cfbbf736e43831c3105f0c91bd790da2d58fb

HiDPI would need a way to propagate the scale factor back-and-forth:
the VM viewer needs to advertise the preferred scale to the guest
compositor, and the guest compositor needs to indicate the scale it
renders with to the VM viewer.

Sounds familiar? Yup, that's exactly the Wayland protocol. Do we really
want to replicate the Wayland protocol in KMS? I'm not so sure.

> > It's getting a bit far off-topic, but google cros team has an out-of-tree
> > (at least I think it's not merged yet) wayland-virtio driver for exactly
> > this use-case. Trying to move towards something like that for fancy
> > virtualized setups sounds like the better approach indeed, with kms just
> > as the bare-bones fallback option.
>
> virtio-gpu got the ability to attach uuids to objects, to allow them
> being identified on the host side. So it could be that wayland-virtio
> still uses kms for framebuffers (disclaimer: don't know how
> wayland-virtio works in detail). But, yes, all the scanout + cursor
> handling would be out of the way, virtio-gpu would "only" handle fast
> buffer sharing.

wayland-virtio is not used with KMS. wayland-virtio proxies the Wayland
protocol between the host and the guest, so the guest doesn't use KMS
in that case.


Re: [PATCH v8 06/14] drm/bridge: imx: Add i.MX8qm/qxp display pixel link support

2022-06-10 Thread Laurent Pinchart
Hi Liu,

On Fri, Jun 10, 2022 at 10:09:19AM +0800, Liu Ying wrote:
> On Thu, 2022-06-09 at 12:30 +0300, Laurent Pinchart wrote:
> > On Thu, Jun 09, 2022 at 02:49:23PM +0800, Liu Ying wrote:
> > > This patch adds a drm bridge driver for i.MX8qm/qxp display pixel
> > > link.
> > > The pixel link forms a standard asynchronous linkage between
> > > pixel sources(display controller or camera module) and pixel
> > > consumers(imaging or displays).  It consists of two distinct
> > > functions, a pixel transfer function and a control interface.
> > > 
> > > Reviewed-by: Robert Foss 
> > > Tested-by: Marcel Ziswiler  # Colibri
> > > iMX8X, LT170410-2WHC, LP156WF1
> > > Signed-off-by: Liu Ying 
> > > ---
> > > Robert, I keep your R-b tag from v5. Let me know if you want me to
> > > drop it, as
> > > v7 contains a fix for checkpatch complaints.
> > > Marcel, as the fix is trivial, I add your T-b tag. Let me know if
> > > you want me
> > > to drop it.
> > > 
> > > v7->v8:
> > > * No change.
> > > 
> > > v6->v7:
> > > * Fix 'Alignment should match open parenthesis' complaints from
> > >   'checkpatch.pl --strict'.
> > > * Add Marcel's T-b tag.
> > > 
> > > v5->v6:
> > > * No change.
> > > 
> > > v4->v5:
> > > * Make a comment occupy a line. (Robert)
> > > * Add Robert's R-b tag.
> > > 
> > > v3->v4:
> > > * No change.
> > > 
> > > v2->v3:
> > > * Drop two macros which help define functions and define them
> > > directly.
> > > * Properly disable all pixel link controls to POR value by calling
> > >   imx8qxp_pixel_link_disable_all_controls() from
> > >   imx8qxp_pixel_link_bridge_probe().
> > > 
> > > v1->v2:
> > > * Rewrite the function to find the next bridge by properly using OF
> > > APIs
> > >   and dropping unnecessary DT validation. (Rob)
> > > 
> > >  drivers/gpu/drm/bridge/imx/Kconfig|   8 +
> > >  drivers/gpu/drm/bridge/imx/Makefile   |   1 +
> > >  .../gpu/drm/bridge/imx/imx8qxp-pixel-link.c   | 429 ++
> > >  3 files changed, 438 insertions(+)
> > >  create mode 100644 drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c
> > > 
> > > diff --git a/drivers/gpu/drm/bridge/imx/Kconfig
> > > b/drivers/gpu/drm/bridge/imx/Kconfig
> > > index f1c91b6814a5..4d1f027d07f8 100644
> > > --- a/drivers/gpu/drm/bridge/imx/Kconfig
> > > +++ b/drivers/gpu/drm/bridge/imx/Kconfig
> > > @@ -6,3 +6,11 @@ config DRM_IMX8QXP_PIXEL_COMBINER
> > >   help
> > > Choose this to enable pixel combiner found in
> > > Freescale i.MX8qm/qxp processors.
> > > +
> > > +config DRM_IMX8QXP_PIXEL_LINK
> > > + tristate "Freescale i.MX8QM/QXP display pixel link"
> > > + depends on OF
> > > + select DRM_KMS_HELPER
> > 
> > Should this depend on (or select) IMX_SCU ?
> 
> Will add 'depends on IMX_SCU'.
> 
> > > + help
> > > +   Choose this to enable display pixel link found in
> > > +   Freescale i.MX8qm/qxp processors.
> > > diff --git a/drivers/gpu/drm/bridge/imx/Makefile
> > > b/drivers/gpu/drm/bridge/imx/Makefile
> > > index 7d7c8d674bf0..c15469fb5789 100644
> > > --- a/drivers/gpu/drm/bridge/imx/Makefile
> > > +++ b/drivers/gpu/drm/bridge/imx/Makefile
> > > @@ -1 +1,2 @@
> > >  obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-
> > > combiner.o
> > > +obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o
> > > diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c 
> > > b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c
> > > new file mode 100644
> > > index ..52b9b96549e1
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c
> > > @@ -0,0 +1,429 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +
> > > +/*
> > > + * Copyright 2020 NXP
> > > + */
> > > +
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +
> > > +#include 
> > > +#include 
> > > +#include 
> > > +
> > > +#include 
> > > +
> > > +#define DRIVER_NAME  "imx8qxp-display-pixel-link"
> > > +#define PL_MAX_MST_ADDR  3
> > > +#define PL_MAX_NEXT_BRIDGES  2
> > > +
> > > +struct imx8qxp_pixel_link {
> > > + struct drm_bridge bridge;
> > > + struct drm_bridge *next_bridge;
> > > + struct device *dev;
> > > + struct imx_sc_ipc *ipc_handle;
> > > + int id;
> > > + int stream_id;
> > > + int dc_id;
> > > + u32 sink_rsc;
> > > + u32 mst_addr;
> > > + u8 mst_addr_ctrl;
> > > + u8 mst_en_ctrl;
> > > + u8 mst_vld_ctrl;
> > > + u8 sync_ctrl;
> > > +};
> > > +
> > > +static void imx8qxp_pixel_link_enable_mst_en(struct imx8qxp_pixel_link 
> > > *pl)
> > > +{
> > > + int ret;
> > > +
> > > + ret = imx_sc_misc_set_control(pl->ipc_handle, pl->sink_rsc,
> > > +   pl->mst_en_ctrl, true);
> > > + if (ret)
> > > + DRM_DEV_ERROR(pl->dev,
> > > +   "failed to enable DC%d stream%d pixel link 
> > > mst_en: %d\n",
> > > +   pl->dc_id, pl->stream_id, ret);
> > > +}
> > > +
> > > +static void imx8qxp_pixel_link_enable_mst_vld(struct imx8qxp_pixel_link 
> > > *pl)
> > > +{
> 

[Bug 210301] *ERROR* IB test failed on gfx (-110) on Ryzen 4750u

2022-06-10 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=210301

ramast (m...@ramast.me) changed:

   What|Removed |Added

 CC||m...@ramast.me

--- Comment #1 from ramast (m...@ramast.me) ---
I had same problem. I found that removing iommu_v2 module from kernel solved
the problem.

-- 
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 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Gerd Hoffmann
  Hi,

> > As Pekka mentionned, I'd also like to have a conversation of how far we 
> > want to
> > push virtualized driver features. I think KMS support is a good feature to 
> > have
> > to spin up a VM and have all of the basics working. However I don't think 
> > it's
> > a good idea to try to plumb an ever-growing list of fancy features
> > (seamless integration of guest windows into the host, HiDPI, multi-monitor,
> > etc) into KMS. You'd just end up re-inventing Wayland or RDP on top of KMS.
> > Instead of re-inventing these, just use RDP or waypipe or X11 forwarding
> > directly.

> > So I think we need to draw a line somewhere, and decide e.g. that 
> > virtualized
> > cursors are fine to add in KMS, but HiDPI is not.

What is the problem with HiDPI?  qemu generates standard edid blobs,
there should be no need to special-case virtualized drivers in any way.

What is the problem with multi-monitor?  That isn't much different than
physical multi-monitor either.

One little thing though:  On physical hardware you just don't know which
monitor is left and which is right until the user tells you.  In case of
a virtual multi-monitor setup we know how the two windows for the two
virtual monitors are arranged on the host and can pass that as hint to
the guest (not sure whenever *that* is the purpose of the
suggested_{x,y} properties).

> It's getting a bit far off-topic, but google cros team has an out-of-tree
> (at least I think it's not merged yet) wayland-virtio driver for exactly
> this use-case. Trying to move towards something like that for fancy
> virtualized setups sounds like the better approach indeed, with kms just
> as the bare-bones fallback option.

virtio-gpu got the ability to attach uuids to objects, to allow them
being identified on the host side.  So it could be that wayland-virtio
still uses kms for framebuffers (disclaimer: don't know how
wayland-virtio works in detail).  But, yes, all the scanout + cursor
handling would be out of the way, virtio-gpu would "only" handle fast
buffer sharing.

take care,
  Gerd



Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Gerd Hoffmann
  Hi,

> >   4. make sure the hotspot property is only set on VIRTUAL_CURSOR planes
> >   and nothing else in the rebased patch series
> 
> Simon also mentioned on irc that these special planes must not expose the
> CRTC_X/Y property, since that doesn't really do much at all. Or is our
> understanding of how this all works for commandeered cursors wrong?

Depends.  In some cases the pointer position is a one-way host->guest
ticket (via tablet device).  In some cases the other direction works too
and the guest can warp the mouse pointer to another place on the host
display.  The guest can't easily figure whenever warp works or not
because that depends on host-side configuration the guest has no insight
to.

take care,
  Gerd



Re: [PATCH v6 0/6] Raspberry PI 4 V3D enablement

2022-06-10 Thread Javier Martinez Canillas
Hello Melissa,

On 6/10/22 13:05, Melissa Wen wrote:
> On 06/08, Javier Martinez Canillas wrote:

[snip]

> 
> Hi Javier,
> 
> Thanks for waiting a little.
> 
> Stefan guided me to the missing part and I'm okay on this serie.
>

No worries and thanks for the testing.
 
> If there's any r-b missing for drm/v3d, you can add mine:
> Reviewed-by: Melissa Wen 
> 
> But if you prefer that I applied them, just let me know.
> 

If you can apply them that's even better since you are more involved
with this driver. I was just trying to be helpful and that's why I
volunteered to push, to prevent this effort to get stalled :)

-- 
Best regards,

Javier Martinez Canillas
Linux Engineering
Red Hat



Re: [PATCH] dt-bindings: display: arm,malidp: remove bogus RQOS property

2022-06-10 Thread Liviu Dudau
On Thu, Jun 09, 2022 at 05:27:29PM +0100, Andre Przywara wrote:
> As Liviu pointed out, the arm,malidp-arqos-high-level property
> mentioned in the original .txt binding was a mistake, and
> arm,malidp-arqos-value needs to take its place.
> 
> The binding commit ce6eb0253cba ("dt/bindings: display: Add optional
> property node define for Mali DP500") mentions the right name in the
> commit message, but has the wrong name in the diff.
> Commit d298e6a27a81 ("drm/arm/mali-dp: Add display QoS interface
> configuration for Mali DP500") uses the property in the driver, but uses
> the shorter name.
> 
> Remove the wrong property from the binding, and use the proper name in
> the example. The actual property was already documented properly.
> 
> Fixes: 2c8b082a3ab1 ("dt-bindings: display: convert Arm Mali-DP to DT schema")
> Link: 
> https://lore.kernel.org/linux-arm-kernel/ynumgeilublhb...@e110455-lin.cambridge.arm.com/
> Signed-off-by: Andre Przywara 
> Reported-by: Liviu Dudau 

Reviewed-by: Liviu Dudau 

Thanks for cleaning this up!

Best regards,
Liviu

> ---
>  Documentation/devicetree/bindings/display/arm,malidp.yaml | 7 +--
>  1 file changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/arm,malidp.yaml 
> b/Documentation/devicetree/bindings/display/arm,malidp.yaml
> index 795a08ac9f128..2a17ec6fc97c0 100644
> --- a/Documentation/devicetree/bindings/display/arm,malidp.yaml
> +++ b/Documentation/devicetree/bindings/display/arm,malidp.yaml
> @@ -71,11 +71,6 @@ properties:
>- description: number of output lines for the green channel (G)
>- description: number of output lines for the blue channel (B)
>  
> -  arm,malidp-arqos-high-level:
> -$ref: /schemas/types.yaml#/definitions/uint32
> -description:
> -  integer describing the ARQoS levels of DP500's QoS signaling
> -
>arm,malidp-arqos-value:
>  $ref: /schemas/types.yaml#/definitions/uint32
>  description:
> @@ -113,7 +108,7 @@ examples:
>  clocks = <>, <>, <>, <>;
>  clock-names = "pxlclk", "mclk", "aclk", "pclk";
>  arm,malidp-output-port-lines = /bits/ 8 <8 8 8>;
> -arm,malidp-arqos-high-level = <0xd000d000>;
> +arm,malidp-arqos-value = <0xd000d000>;
>  
>  port {
>  dp0_output: endpoint {
> -- 
> 2.25.1
> 

-- 

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


[PATCH v2 10/14] drm/vc4: crtc: Move the BO handling out of common page-flip callback

2022-06-10 Thread Maxime Ripard
We'll soon introduce another completion callback source that won't need
to use the BO reference counting, so let's move it around to create a
function we will be able to share between both callbacks.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 34 --
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 1f247c037ce0..0410db97b9d1 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -802,21 +802,8 @@ vc4_async_page_flip_complete(struct vc4_async_flip_state 
*flip_state)
drm_crtc_vblank_put(crtc);
drm_framebuffer_put(flip_state->fb);
 
-   /* Decrement the BO usecnt in order to keep the inc/dec calls balanced
-* when the planes are updated through the async update path.
-* FIXME: we should move to generic async-page-flip when it's
-* available, so that we can get rid of this hand-made cleanup_fb()
-* logic.
-*/
-   if (flip_state->old_fb) {
-   struct drm_gem_cma_object *cma_bo;
-   struct vc4_bo *bo;
-
-   cma_bo = drm_fb_cma_get_gem_obj(flip_state->old_fb, 0);
-   bo = to_vc4_bo(_bo->base);
-   vc4_bo_dec_usecnt(bo);
+   if (flip_state->old_fb)
drm_framebuffer_put(flip_state->old_fb);
-   }
 
kfree(flip_state);
 }
@@ -825,8 +812,27 @@ static void vc4_async_page_flip_seqno_complete(struct 
vc4_seqno_cb *cb)
 {
struct vc4_async_flip_state *flip_state =
container_of(cb, struct vc4_async_flip_state, cb.seqno);
+   struct vc4_bo *bo = NULL;
+
+   if (flip_state->old_fb) {
+   struct drm_gem_cma_object *cma_bo =
+   drm_fb_cma_get_gem_obj(flip_state->old_fb, 0);
+   bo = to_vc4_bo(_bo->base);
+   }
 
vc4_async_page_flip_complete(flip_state);
+
+   /*
+* Decrement the BO usecnt in order to keep the inc/dec
+* calls balanced when the planes are updated through
+* the async update path.
+*
+* FIXME: we should move to generic async-page-flip when
+* it's available, so that we can get rid of this
+* hand-made cleanup_fb() logic.
+*/
+   if (bo)
+   vc4_bo_dec_usecnt(bo);
 }
 
 /* Implements async (non-vblank-synced) page flips.
-- 
2.36.1



[PATCH v2 14/14] drm/vc4: Warn if some v3d code is run on BCM2711

2022-06-10 Thread Maxime Ripard
The BCM2711 has a separate driver for the v3d, and thus we can't call
into any of the driver entrypoints that rely on the v3d being there.

Let's add a bunch of checks and complain loudly if that ever happen.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_bo.c   | 49 ++
 drivers/gpu/drm/vc4/vc4_drv.c  | 11 +
 drivers/gpu/drm/vc4/vc4_drv.h  |  6 +++
 drivers/gpu/drm/vc4/vc4_gem.c  | 40 ++
 drivers/gpu/drm/vc4/vc4_irq.c  | 16 +++
 drivers/gpu/drm/vc4/vc4_kms.c  |  4 ++
 drivers/gpu/drm/vc4/vc4_perfmon.c  | 47 -
 drivers/gpu/drm/vc4/vc4_render_cl.c|  4 ++
 drivers/gpu/drm/vc4/vc4_v3d.c  | 15 +++
 drivers/gpu/drm/vc4/vc4_validate.c | 16 +++
 drivers/gpu/drm/vc4/vc4_validate_shaders.c |  4 ++
 11 files changed, 211 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 3ca16d682fc0..b8d856312846 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -248,6 +248,9 @@ void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo)
 {
struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return;
+
mutex_lock(>purgeable.lock);
list_add_tail(>size_head, >purgeable.list);
vc4->purgeable.num++;
@@ -259,6 +262,9 @@ static void vc4_bo_remove_from_purgeable_pool_locked(struct 
vc4_bo *bo)
 {
struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return;
+
/* list_del_init() is used here because the caller might release
 * the purgeable lock in order to acquire the madv one and update the
 * madv status.
@@ -387,6 +393,9 @@ struct drm_gem_object *vc4_create_object(struct drm_device 
*dev, size_t size)
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_bo *bo;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return ERR_PTR(-ENODEV);
+
bo = kzalloc(sizeof(*bo), GFP_KERNEL);
if (!bo)
return ERR_PTR(-ENOMEM);
@@ -413,6 +422,9 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t 
unaligned_size,
struct drm_gem_cma_object *cma_obj;
struct vc4_bo *bo;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return ERR_PTR(-ENODEV);
+
if (size == 0)
return ERR_PTR(-EINVAL);
 
@@ -475,9 +487,13 @@ int vc4_bo_dumb_create(struct drm_file *file_priv,
   struct drm_device *dev,
   struct drm_mode_create_dumb *args)
 {
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_bo *bo = NULL;
int ret;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
ret = vc4_dumb_fixup_args(args);
if (ret)
return ret;
@@ -598,8 +614,12 @@ static void vc4_bo_cache_time_work(struct work_struct 
*work)
 
 int vc4_bo_inc_usecnt(struct vc4_bo *bo)
 {
+   struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
int ret;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
/* Fast path: if the BO is already retained by someone, no need to
 * check the madv status.
 */
@@ -634,6 +654,11 @@ int vc4_bo_inc_usecnt(struct vc4_bo *bo)
 
 void vc4_bo_dec_usecnt(struct vc4_bo *bo)
 {
+   struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
+
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return;
+
/* Fast path: if the BO is still retained by someone, no need to test
 * the madv value.
 */
@@ -753,6 +778,9 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
struct vc4_bo *bo = NULL;
int ret;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
ret = vc4_grab_bin_bo(vc4, vc4file);
if (ret)
return ret;
@@ -776,9 +804,13 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
 int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
  struct drm_file *file_priv)
 {
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
struct drm_vc4_mmap_bo *args = data;
struct drm_gem_object *gem_obj;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
if (!gem_obj) {
DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
@@ -802,6 +834,9 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void 
*data,
struct vc4_bo *bo = NULL;
int ret;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
if (args->size == 0)
return -EINVAL;
 
@@ -872,11 +907,15 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void 
*data,
 int 

[PATCH v2 11/14] drm/vc4: crtc: Move the BO Handling out of Common Page-Flip Handler

2022-06-10 Thread Maxime Ripard
The function vc4_async_page_flip() handles asynchronous page-flips in
the vc4 driver.

However, it mixes some generic code with code that should only be run on
older generations that have the GPU handled by the vc4 driver.

Let's split the generic part out of vc4_async_page_flip() and into a
common function that we be reusable by an handler made for the BCM2711.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 73 ++
 1 file changed, 48 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 0410db97b9d1..c00fb964c534 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -835,40 +835,21 @@ static void vc4_async_page_flip_seqno_complete(struct 
vc4_seqno_cb *cb)
vc4_bo_dec_usecnt(bo);
 }
 
-/* Implements async (non-vblank-synced) page flips.
- *
- * The page flip ioctl needs to return immediately, so we grab the
- * modeset semaphore on the pipe, and queue the address update for
- * when V3D is done with the BO being flipped to.
- */
-static int vc4_async_page_flip(struct drm_crtc *crtc,
-  struct drm_framebuffer *fb,
-  struct drm_pending_vblank_event *event,
-  uint32_t flags)
+static int
+vc4_async_page_flip_common(struct drm_crtc *crtc,
+  struct drm_framebuffer *fb,
+  struct drm_pending_vblank_event *event,
+  uint32_t flags)
 {
struct drm_device *dev = crtc->dev;
struct drm_plane *plane = crtc->primary;
-   int ret = 0;
struct vc4_async_flip_state *flip_state;
struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
struct vc4_bo *bo = to_vc4_bo(_bo->base);
 
-   /* Increment the BO usecnt here, so that we never end up with an
-* unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the
-* plane is later updated through the non-async path.
-* FIXME: we should move to generic async-page-flip when it's
-* available, so that we can get rid of this hand-made prepare_fb()
-* logic.
-*/
-   ret = vc4_bo_inc_usecnt(bo);
-   if (ret)
-   return ret;
-
flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL);
-   if (!flip_state) {
-   vc4_bo_dec_usecnt(bo);
+   if (!flip_state)
return -ENOMEM;
-   }
 
drm_framebuffer_get(fb);
flip_state->fb = fb;
@@ -902,6 +883,48 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
return 0;
 }
 
+/* Implements async (non-vblank-synced) page flips.
+ *
+ * The page flip ioctl needs to return immediately, so we grab the
+ * modeset semaphore on the pipe, and queue the address update for
+ * when V3D is done with the BO being flipped to.
+ */
+static int vc4_async_page_flip(struct drm_crtc *crtc,
+  struct drm_framebuffer *fb,
+  struct drm_pending_vblank_event *event,
+  uint32_t flags)
+{
+   struct drm_device *dev = crtc->dev;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
+   struct vc4_bo *bo = to_vc4_bo(_bo->base);
+   int ret;
+
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
+   /*
+* Increment the BO usecnt here, so that we never end up with an
+* unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the
+* plane is later updated through the non-async path.
+*
+* FIXME: we should move to generic async-page-flip when
+* it's available, so that we can get rid of this
+* hand-made prepare_fb() logic.
+*/
+   ret = vc4_bo_inc_usecnt(bo);
+   if (ret)
+   return ret;
+
+   ret = vc4_async_page_flip_common(crtc, fb, event, flags);
+   if (ret) {
+   vc4_bo_dec_usecnt(bo);
+   return ret;
+   }
+
+   return 0;
+}
+
 int vc4_page_flip(struct drm_crtc *crtc,
  struct drm_framebuffer *fb,
  struct drm_pending_vblank_event *event,
-- 
2.36.1



[PATCH v2 05/14] drm/vc4: drv: Register a different driver on BCM2711

2022-06-10 Thread Maxime Ripard
Prior to the BCM2711/RaspberryPi4, the GPU was a part of the display
components of the SoC. It was thus a part of the vc4 driver.

However, with the BCM2711, it got split out and thus the v3d driver was
created. The vc4 driver now only handles the display part.

We didn't properly split out the code when doing the BCM2711 support
though, and most of the code around buffer allocations is still
involved, even though it doesn't have the backing hardware anymore.

Let's start the split out by creating a new drm_driver that only reports
and uses what we support on the BCM2711. The ioctl were properly
filtered already, but we were still exposing a .gem_create_object hook,
as well as having an .open and .postclose hooks which are only relevant
on older generations.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_drv.c | 51 ---
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index eb08940028d3..528a1e2761f1 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -76,6 +76,19 @@ int vc4_dumb_fixup_args(struct drm_mode_create_dumb *args)
return 0;
 }
 
+static int vc5_dumb_create(struct drm_file *file_priv,
+  struct drm_device *dev,
+  struct drm_mode_create_dumb *args)
+{
+   int ret;
+
+   ret = vc4_dumb_fixup_args(args);
+   if (ret)
+   return ret;
+
+   return drm_gem_cma_dumb_create_internal(file_priv, dev, args);
+}
+
 static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv)
 {
@@ -173,7 +186,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(VC4_PERFMON_GET_VALUES, vc4_perfmon_get_values_ioctl, 
DRM_RENDER_ALLOW),
 };
 
-static struct drm_driver vc4_drm_driver = {
+static const struct drm_driver vc4_drm_driver = {
.driver_features = (DRIVER_MODESET |
DRIVER_ATOMIC |
DRIVER_GEM |
@@ -202,6 +215,27 @@ static struct drm_driver vc4_drm_driver = {
.patchlevel = DRIVER_PATCHLEVEL,
 };
 
+static const struct drm_driver vc5_drm_driver = {
+   .driver_features = (DRIVER_MODESET |
+   DRIVER_ATOMIC |
+   DRIVER_GEM),
+
+#if defined(CONFIG_DEBUG_FS)
+   .debugfs_init = vc4_debugfs_init,
+#endif
+
+   DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(vc5_dumb_create),
+
+   .fops = _drm_fops,
+
+   .name = DRIVER_NAME,
+   .desc = DRIVER_DESC,
+   .date = DRIVER_DATE,
+   .major = DRIVER_MAJOR,
+   .minor = DRIVER_MINOR,
+   .patchlevel = DRIVER_PATCHLEVEL,
+};
+
 static void vc4_match_add_drivers(struct device *dev,
  struct component_match **match,
  struct platform_driver *const *drivers,
@@ -225,6 +259,7 @@ static void vc4_match_add_drivers(struct device *dev,
 static int vc4_drm_bind(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
+   const struct drm_driver *driver;
struct rpi_firmware *firmware = NULL;
struct drm_device *drm;
struct vc4_dev *vc4;
@@ -236,14 +271,12 @@ static int vc4_drm_bind(struct device *dev)
dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
is_vc5 = of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5");
+   if (is_vc5)
+   driver = _drm_driver;
+   else
+   driver = _drm_driver;
 
-   /* If VC4 V3D is missing, don't advertise render nodes. */
-   node = of_find_matching_node_and_match(NULL, vc4_v3d_dt_match, NULL);
-   if (!node || !of_device_is_available(node))
-   vc4_drm_driver.driver_features &= ~DRIVER_RENDER;
-   of_node_put(node);
-
-   vc4 = devm_drm_dev_alloc(dev, _drm_driver, struct vc4_dev, base);
+   vc4 = devm_drm_dev_alloc(dev, driver, struct vc4_dev, base);
if (IS_ERR(vc4))
return PTR_ERR(vc4);
vc4->is_vc5 = is_vc5;
@@ -275,7 +308,7 @@ static int vc4_drm_bind(struct device *dev)
return -EPROBE_DEFER;
}
 
-   ret = drm_aperture_remove_framebuffers(false, _drm_driver);
+   ret = drm_aperture_remove_framebuffers(false, driver);
if (ret)
return ret;
 
-- 
2.36.1



[PATCH v2 13/14] drm/vc4: crtc: Fix out of order frames during asynchronous page flips

2022-06-10 Thread Maxime Ripard
When doing an asynchronous page flip (PAGE_FLIP ioctl with the
DRM_MODE_PAGE_FLIP_ASYNC flag set), the current code waits for the
possible GPU buffer being rendered through a call to
vc4_queue_seqno_cb().

On the BCM2835-37, the GPU driver is part of the vc4 driver and that
function is defined in vc4_gem.c to wait for the buffer to be rendered,
and once it's done, call a callback.

However, on the BCM2711 used on the RaspberryPi4, the GPU driver is
separate (v3d) and that function won't do anything. This was working
because we were going into a path, due to uninitialized variables, that
was always scheduling the callback.

However, we were never actually waiting for the buffer to be rendered
which was resulting in frames being displayed out of order.

The generic API to signal those kind of completion in the kernel are the
DMA fences, and fortunately the v3d drivers supports them and signal
when its job is done. That API also provides an equivalent function that
allows to have a callback being executed when the fence is signalled as
done.

Let's change our driver a bit to rely on the previous function for the
older SoCs, and on DMA fences for the BCM2711.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 50 +++---
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index a3c04d6cbd20..9355213dc883 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -776,6 +776,7 @@ struct vc4_async_flip_state {
struct drm_pending_vblank_event *event;
 
union {
+   struct dma_fence_cb fence;
struct vc4_seqno_cb seqno;
} cb;
 };
@@ -835,6 +836,50 @@ static void vc4_async_page_flip_seqno_complete(struct 
vc4_seqno_cb *cb)
vc4_bo_dec_usecnt(bo);
 }
 
+static void vc4_async_page_flip_fence_complete(struct dma_fence *fence,
+  struct dma_fence_cb *cb)
+{
+   struct vc4_async_flip_state *flip_state =
+   container_of(cb, struct vc4_async_flip_state, cb.fence);
+
+   vc4_async_page_flip_complete(flip_state);
+   dma_fence_put(fence);
+}
+
+static int vc4_async_set_fence_cb(struct drm_device *dev,
+ struct vc4_async_flip_state *flip_state)
+{
+   struct drm_framebuffer *fb = flip_state->fb;
+   struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct dma_fence *fence;
+   int ret;
+
+   if (!vc4->is_vc5) {
+   struct vc4_bo *bo = to_vc4_bo(_bo->base);
+
+   return vc4_queue_seqno_cb(dev, _state->cb.seqno, bo->seqno,
+ vc4_async_page_flip_seqno_complete);
+   }
+
+   ret = dma_resv_get_singleton(cma_bo->base.resv, DMA_RESV_USAGE_READ, 
);
+   if (ret)
+   return ret;
+
+   /* If there's no fence, complete the page flip immediately */
+   if (!fence) {
+   vc4_async_page_flip_fence_complete(fence, 
_state->cb.fence);
+   return 0;
+   }
+
+   /* If the fence has already been completed, complete the page flip */
+   if (dma_fence_add_callback(fence, _state->cb.fence,
+  vc4_async_page_flip_fence_complete))
+   vc4_async_page_flip_fence_complete(fence, 
_state->cb.fence);
+
+   return 0;
+}
+
 static int
 vc4_async_page_flip_common(struct drm_crtc *crtc,
   struct drm_framebuffer *fb,
@@ -844,8 +889,6 @@ vc4_async_page_flip_common(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct drm_plane *plane = crtc->primary;
struct vc4_async_flip_state *flip_state;
-   struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
-   struct vc4_bo *bo = to_vc4_bo(_bo->base);
 
flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL);
if (!flip_state)
@@ -876,8 +919,7 @@ vc4_async_page_flip_common(struct drm_crtc *crtc,
 */
drm_atomic_set_fb_for_plane(plane->state, fb);
 
-   vc4_queue_seqno_cb(dev, _state->cb.seqno, bo->seqno,
-  vc4_async_page_flip_seqno_complete);
+   vc4_async_set_fence_cb(dev, flip_state);
 
/* Driver takes ownership of state on successful async commit. */
return 0;
-- 
2.36.1



[PATCH v2 12/14] drm/vc4: crtc: Don't call into BO Handling on Async Page-Flips on BCM2711

2022-06-10 Thread Maxime Ripard
The BCM2711 doesn't have a v3d GPU so we don't want to call into its BO
management code. Let's create an asynchronous page-flip handler for the
BCM2711 that just calls into the common code.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index c00fb964c534..a3c04d6cbd20 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -925,16 +925,31 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
return 0;
 }
 
+static int vc5_async_page_flip(struct drm_crtc *crtc,
+  struct drm_framebuffer *fb,
+  struct drm_pending_vblank_event *event,
+  uint32_t flags)
+{
+   return vc4_async_page_flip_common(crtc, fb, event, flags);
+}
+
 int vc4_page_flip(struct drm_crtc *crtc,
  struct drm_framebuffer *fb,
  struct drm_pending_vblank_event *event,
  uint32_t flags,
  struct drm_modeset_acquire_ctx *ctx)
 {
-   if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
-   return vc4_async_page_flip(crtc, fb, event, flags);
-   else
+   if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
+   struct drm_device *dev = crtc->dev;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+   if (vc4->is_vc5)
+   return vc5_async_page_flip(crtc, fb, event, flags);
+   else
+   return vc4_async_page_flip(crtc, fb, event, flags);
+   } else {
return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx);
+   }
 }
 
 struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
-- 
2.36.1



[PATCH v2 06/14] drm/vc4: kms: Register a different drm_mode_config_funcs on BCM2711

2022-06-10 Thread Maxime Ripard
On the BCM2711, our current definition of drm_mode_config_funcs uses the
custom vc4_fb_create().

However, that function relies on the buffer allocation path that was
relying on the GPU, and is no longer relevant.

Let's create another drm_mode_config_funcs structure that we will
register on the BCM2711.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_kms.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 3c232d85ab85..1d3b31fb71ea 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -997,6 +997,12 @@ static const struct drm_mode_config_funcs vc4_mode_funcs = 
{
.fb_create = vc4_fb_create,
 };
 
+static const struct drm_mode_config_funcs vc5_mode_funcs = {
+   .atomic_check = vc4_atomic_check,
+   .atomic_commit = drm_atomic_helper_commit,
+   .fb_create = drm_gem_fb_create,
+};
+
 int vc4_kms_load(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -1031,7 +1037,7 @@ int vc4_kms_load(struct drm_device *dev)
dev->mode_config.max_height = 2048;
}
 
-   dev->mode_config.funcs = _mode_funcs;
+   dev->mode_config.funcs = vc4->is_vc5 ? _mode_funcs : 
_mode_funcs;
dev->mode_config.helper_private = _mode_config_helpers;
dev->mode_config.preferred_depth = 24;
dev->mode_config.async_page_flip = true;
-- 
2.36.1



[PATCH v2 09/14] drm/vc4: crtc: Use an union to store the page flip callback

2022-06-10 Thread Maxime Ripard
We'll need to extend the vc4_async_flip_state structure to rely on
another callback implementation, so let's move the current one into a
union.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index dd5fb25d0f43..1f247c037ce0 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -775,17 +775,17 @@ struct vc4_async_flip_state {
struct drm_framebuffer *old_fb;
struct drm_pending_vblank_event *event;
 
-   struct vc4_seqno_cb cb;
+   union {
+   struct vc4_seqno_cb seqno;
+   } cb;
 };
 
 /* Called when the V3D execution for the BO being flipped to is done, so that
  * we can actually update the plane's address to point to it.
  */
 static void
-vc4_async_page_flip_complete(struct vc4_seqno_cb *cb)
+vc4_async_page_flip_complete(struct vc4_async_flip_state *flip_state)
 {
-   struct vc4_async_flip_state *flip_state =
-   container_of(cb, struct vc4_async_flip_state, cb);
struct drm_crtc *crtc = flip_state->crtc;
struct drm_device *dev = crtc->dev;
struct drm_plane *plane = crtc->primary;
@@ -821,6 +821,14 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb)
kfree(flip_state);
 }
 
+static void vc4_async_page_flip_seqno_complete(struct vc4_seqno_cb *cb)
+{
+   struct vc4_async_flip_state *flip_state =
+   container_of(cb, struct vc4_async_flip_state, cb.seqno);
+
+   vc4_async_page_flip_complete(flip_state);
+}
+
 /* Implements async (non-vblank-synced) page flips.
  *
  * The page flip ioctl needs to return immediately, so we grab the
@@ -881,8 +889,8 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
 */
drm_atomic_set_fb_for_plane(plane->state, fb);
 
-   vc4_queue_seqno_cb(dev, _state->cb, bo->seqno,
-  vc4_async_page_flip_complete);
+   vc4_queue_seqno_cb(dev, _state->cb.seqno, bo->seqno,
+  vc4_async_page_flip_seqno_complete);
 
/* Driver takes ownership of state on successful async commit. */
return 0;
-- 
2.36.1



[PATCH v2 08/14] drm/vc4: drv: Skip BO Backend Initialization on BCM2711

2022-06-10 Thread Maxime Ripard
On the BCM2711, we currently call the vc4_bo_cache_init() and
vc4_gem_init() functions. These functions initialize the BO and GEM
backends.

However, this code was initially created to accomodate the requirements
of the GPU on the older SoCs, while the BCM2711 has a separate driver
for it. So let's just skip these calls when we're on a newer hardware.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_drv.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 528a1e2761f1..ef4ab0563168 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -285,19 +285,23 @@ static int vc4_drm_bind(struct device *dev)
platform_set_drvdata(pdev, drm);
INIT_LIST_HEAD(>debugfs_list);
 
-   mutex_init(>bin_bo_lock);
+   if (!is_vc5) {
+   mutex_init(>bin_bo_lock);
 
-   ret = vc4_bo_cache_init(drm);
-   if (ret)
-   return ret;
+   ret = vc4_bo_cache_init(drm);
+   if (ret)
+   return ret;
+   }
 
ret = drmm_mode_config_init(drm);
if (ret)
return ret;
 
-   ret = vc4_gem_init(drm);
-   if (ret)
-   return ret;
+   if (!is_vc5) {
+   ret = vc4_gem_init(drm);
+   if (ret)
+   return ret;
+   }
 
node = of_find_compatible_node(NULL, NULL, 
"raspberrypi,bcm2835-firmware");
if (node) {
-- 
2.36.1



[PATCH v2 07/14] drm/vc4: plane: Register a different drm_plane_helper_funcs on BCM2711

2022-06-10 Thread Maxime Ripard
On the BCM2711, our current definition of drm_plane_helper_funcs uses
the custom vc4_prepare_fb() and vc4_cleanup_fb().

Those functions rely on the buffer allocation path that was relying on
the GPU, and is no longer relevant.

Let's create another drm_plane_helper_funcs structure that we will
register on the BCM2711.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_plane.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index ba7359516d75..1e866dc00ac3 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -1389,6 +1389,13 @@ static const struct drm_plane_helper_funcs 
vc4_plane_helper_funcs = {
.atomic_async_update = vc4_plane_atomic_async_update,
 };
 
+static const struct drm_plane_helper_funcs vc5_plane_helper_funcs = {
+   .atomic_check = vc4_plane_atomic_check,
+   .atomic_update = vc4_plane_atomic_update,
+   .atomic_async_check = vc4_plane_atomic_async_check,
+   .atomic_async_update = vc4_plane_atomic_async_update,
+};
+
 static bool vc4_format_mod_supported(struct drm_plane *plane,
 uint32_t format,
 uint64_t modifier)
@@ -1493,7 +1500,10 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
if (ret)
return ERR_PTR(ret);
 
-   drm_plane_helper_add(plane, _plane_helper_funcs);
+   if (vc4->is_vc5)
+   drm_plane_helper_add(plane, _plane_helper_funcs);
+   else
+   drm_plane_helper_add(plane, _plane_helper_funcs);
 
drm_plane_create_alpha_property(plane);
drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
-- 
2.36.1



[PATCH v2 03/14] drm/vc4: bo: Rename vc4_dumb_create

2022-06-10 Thread Maxime Ripard
We're going to add a new variant of the dumb BO allocation function, so
let's rename vc4_dumb_create() to something a bit more specific.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_bo.c  | 6 +++---
 drivers/gpu/drm/vc4/vc4_drv.c | 2 +-
 drivers/gpu/drm/vc4/vc4_drv.h | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 49c0f2ac868b..6d505da6b6cf 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -471,9 +471,9 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t 
unaligned_size,
return bo;
 }
 
-int vc4_dumb_create(struct drm_file *file_priv,
-   struct drm_device *dev,
-   struct drm_mode_create_dumb *args)
+int vc4_bo_dumb_create(struct drm_file *file_priv,
+  struct drm_device *dev,
+  struct drm_mode_create_dumb *args)
 {
int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
struct vc4_bo *bo = NULL;
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 53067525b586..5f39e40ef238 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -175,7 +175,7 @@ static struct drm_driver vc4_drm_driver = {
 
.gem_create_object = vc4_create_object,
 
-   DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(vc4_dumb_create),
+   DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(vc4_bo_dumb_create),
 
.ioctls = vc4_drm_ioctls,
.num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 82453a3bcffe..37c93654480f 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -814,9 +814,9 @@ struct vc4_validated_shader_info {
 struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size);
 struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size,
 bool from_cache, enum vc4_kernel_bo_type type);
-int vc4_dumb_create(struct drm_file *file_priv,
-   struct drm_device *dev,
-   struct drm_mode_create_dumb *args);
+int vc4_bo_dumb_create(struct drm_file *file_priv,
+  struct drm_device *dev,
+  struct drm_mode_create_dumb *args);
 int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
 int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
-- 
2.36.1



[PATCH v2 02/14] drm/vc4: Consolidate Hardware Revision Check

2022-06-10 Thread Maxime Ripard
A new generation of controller has been introduced with the
BCM2711/RaspberryPi4. This generation needs a bunch of quirks, and over
time we've piled on a number of checks in most parts of the drivers.

All these checks are performed several times, and are not always
consistent. Let's create a single, global, variable to hold it and use
it everywhere.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c  |  6 +++---
 drivers/gpu/drm/vc4/vc4_drv.c   |  4 
 drivers/gpu/drm/vc4/vc4_drv.h   |  6 +++---
 drivers/gpu/drm/vc4/vc4_hvs.c   | 18 +-
 drivers/gpu/drm/vc4/vc4_kms.c   | 12 +---
 drivers/gpu/drm/vc4/vc4_plane.c | 13 ++---
 6 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 59b20c8f132b..dd5fb25d0f43 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -256,7 +256,7 @@ static u32 vc4_get_fifo_full_level(struct vc4_crtc 
*vc4_crtc, u32 format)
 * Removing 1 from the FIFO full level however
 * seems to completely remove that issue.
 */
-   if (!vc4->hvs->hvs5)
+   if (!vc4->is_vc5)
return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1;
 
return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX;
@@ -389,7 +389,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, 
struct drm_encoder *encode
if (is_dsi)
CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
 
-   if (vc4->hvs->hvs5)
+   if (vc4->is_vc5)
CRTC_WRITE(PV_MUX_CFG,
   VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP,
 PV_MUX_CFG_RGB_PIXEL_MUX_MODE));
@@ -1149,7 +1149,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc 
*vc4_crtc,
  crtc_funcs, NULL);
drm_crtc_helper_add(crtc, crtc_helper_funcs);
 
-   if (!vc4->hvs->hvs5) {
+   if (!vc4->is_vc5) {
drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
 
drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 162bc18e7497..53067525b586 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -217,10 +217,13 @@ static int vc4_drm_bind(struct device *dev)
struct vc4_dev *vc4;
struct device_node *node;
struct drm_crtc *crtc;
+   bool is_vc5;
int ret = 0;
 
dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
+   is_vc5 = of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5");
+
/* If VC4 V3D is missing, don't advertise render nodes. */
node = of_find_matching_node_and_match(NULL, vc4_v3d_dt_match, NULL);
if (!node || !of_device_is_available(node))
@@ -230,6 +233,7 @@ static int vc4_drm_bind(struct device *dev)
vc4 = devm_drm_dev_alloc(dev, _drm_driver, struct vc4_dev, base);
if (IS_ERR(vc4))
return PTR_ERR(vc4);
+   vc4->is_vc5 = is_vc5;
 
drm = >base;
platform_set_drvdata(pdev, drm);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 15e0c2ac3940..82453a3bcffe 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -74,6 +74,8 @@ struct vc4_perfmon {
 struct vc4_dev {
struct drm_device base;
 
+   bool is_vc5;
+
unsigned int irq;
 
struct vc4_hvs *hvs;
@@ -316,6 +318,7 @@ struct vc4_v3d {
 };
 
 struct vc4_hvs {
+   struct vc4_dev *vc4;
struct platform_device *pdev;
void __iomem *regs;
u32 __iomem *dlist;
@@ -333,9 +336,6 @@ struct vc4_hvs {
struct drm_mm_node mitchell_netravali_filter;
 
struct debugfs_regset32 regset;
-
-   /* HVS version 5 flag, therefore requires updated dlist structures */
-   bool hvs5;
 };
 
 struct vc4_plane {
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 2a58fc421cf6..ba2c8e5a9b64 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -220,10 +220,11 @@ u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, 
unsigned int fifo)
 
 int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output)
 {
+   struct vc4_dev *vc4 = hvs->vc4;
u32 reg;
int ret;
 
-   if (!hvs->hvs5)
+   if (!vc4->is_vc5)
return output;
 
switch (output) {
@@ -273,6 +274,7 @@ int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, 
unsigned int output)
 static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc,
struct drm_display_mode *mode, bool oneshot)
 {
+   struct vc4_dev *vc4 = hvs->vc4;
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct 

  1   2   3   >