Re: [PATCH 2/2] drm/i915: Remove the vm open count

2022-03-02 Thread Thomas Hellström
On Tue, 2022-03-01 at 19:45 -0800, Niranjana Vishwanathapura wrote:
> On Tue, Feb 22, 2022 at 06:10:30PM +0100, Thomas Hellström wrote:
> > vms are not getting properly closed. Rather than fixing that,
> > Remove the vm open count and instead rely on the vm refcount.
> > 
> > The vm open count existed solely to break the strong references the
> > vmas had on the vms. Now instead make those references weak and
> > ensure vmas are destroyed when the vm is destroyed.
> > 
> > Unfortunately if the vm destructor and the object destructor both
> > wants to destroy a vma, that may lead to a race in that the vm
> > destructor just unbinds the vma and leaves the actual vma
> > destruction
> > to the object destructor. However in order for the object
> > destructor
> > to ensure the vma is unbound it needs to grab the vm mutex. In
> > order
> > to keep the vm mutex alive until the object destructor is done with
> > it, somewhat hackishly grab a vm_resv refcount that is released
> > late
> > in the vma destruction process, when the vm mutex is no longer
> > needed.
> > 
> > Cc: 
> > Co-developed-by: Niranjana Vishwanathapura
> > 
> > Signed-off-by: Niranjana Vishwanathapura
> > 
> > Signed-off-by: Thomas Hellström 
> > ---
> > drivers/gpu/drm/i915/display/intel_dpt.c  |  2 +-
> > drivers/gpu/drm/i915/gem/i915_gem_context.c   | 29 ++-
> > .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  6 ++
> > .../gpu/drm/i915/gem/selftests/mock_context.c |  5 +-
> > drivers/gpu/drm/i915/gt/gen6_ppgtt.c  |  2 +-
> > drivers/gpu/drm/i915/gt/intel_ggtt.c  | 25 ++
> > drivers/gpu/drm/i915/gt/intel_gtt.c   | 48 ---
> > drivers/gpu/drm/i915/gt/intel_gtt.h   | 56 
> > drivers/gpu/drm/i915/gt/selftest_execlists.c  | 86 +---
> > ---
> > drivers/gpu/drm/i915/i915_gem.c   |  6 +-
> > drivers/gpu/drm/i915/i915_vma.c   | 55 
> > drivers/gpu/drm/i915/i915_vma_resource.c  |  2 +-
> > drivers/gpu/drm/i915/i915_vma_resource.h  |  6 ++
> > drivers/gpu/drm/i915/i915_vma_types.h |  7 ++
> > drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  4 +-
> > 15 files changed, 179 insertions(+), 160 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c
> > b/drivers/gpu/drm/i915/display/intel_dpt.c
> > index c2f8f853db90..6920669bc571 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dpt.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dpt.c
> > @@ -298,5 +298,5 @@ void intel_dpt_destroy(struct
> > i915_address_space *vm)
> > {
> > struct i915_dpt *dpt = i915_vm_to_dpt(vm);
> > 
> > -   i915_vm_close(&dpt->vm);
> > +   i915_vm_put(&dpt->vm);
> > }
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > index ebbac2ea0833..41404f043741 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > @@ -1440,8 +1440,6 @@ static void set_closed_name(struct
> > i915_gem_context *ctx)
> > 
> > static void context_close(struct i915_gem_context *ctx)
> > {
> > -   struct i915_address_space *vm;
> > -
> > /* Flush any concurrent set_engines() */
> > mutex_lock(&ctx->engines_mutex);
> > unpin_engines(__context_engines_static(ctx));
> > @@ -1453,19 +1451,6 @@ static void context_close(struct
> > i915_gem_context *ctx)
> > 
> > set_closed_name(ctx);
> > 
> > -   vm = ctx->vm;
> > -   if (vm) {
> > -   /* i915_vm_close drops the final reference, which
> > is a bit too
> > -    * early and could result in surprises with
> > concurrent
> > -    * operations racing with thist ctx close. Keep a
> > full reference
> > -    * until the end.
> > -    */
> > -   i915_vm_get(vm);
> > -   i915_vm_close(vm);
> > -   }
> > -
> > -   ctx->file_priv = ERR_PTR(-EBADF);
> > -
> > /*
> >  * The LUT uses the VMA as a backpointer to unref the
> > object,
> >  * so we need to clear the LUT before we close all the VMA
> > (inside
> > @@ -1473,6 +1458,8 @@ static void context_close(struct
> > i915_gem_context *ctx)
> >  */
> > lut_close(ctx);
> > 
> > +   ctx->file_priv = ERR_PTR(-EBADF);
> > +
> > spin_lock(&ctx->i915->gem.contexts.lock);
> > list_del(&ctx->link);
> > spin_unlock(&ctx->i915->gem.contexts.lock);
> > @@ -1571,12 +1558,8 @@ i915_gem_create_context(struct
> > drm_i915_private *i915,
> > }
> > vm = &ppgtt->vm;
> > }
> > -   if (vm) {
> > -   ctx->vm = i915_vm_open(vm);
> > -
> > -   /* i915_vm_open() takes a reference */
> > -   i915_vm_put(vm);
> > -   }
> > +   if (vm)
> > +   ctx->vm = vm;
> > 
> > mutex_init(&ctx->engines_mutex);
> > if (pc->num_user_engines >= 0) {
> > @@ -1626,7 +1609,7 @@

[v3 0/4] enhanced edid driver compatibility

2022-03-02 Thread Lee Shawn C
Support to parse multiple CEA extension blocks and HF-EEODB to
extend drm edid driver's capability.

Lee Shawn C (4):
  drm/edid: seek for available CEA block from specific EDID block index
  drm/edid: parse multiple CEA extension block
  drm/edid: read HF-EEODB ext block
  drm/edid: parse HF-EEODB CEA extension block

 drivers/gpu/drm/drm_connector.c |   8 +-
 drivers/gpu/drm/drm_displayid.c |   5 +-
 drivers/gpu/drm/drm_edid.c  | 158 +++-
 include/drm/drm_edid.h  |   4 +-
 4 files changed, 128 insertions(+), 47 deletions(-)

-- 
2.31.1



[v3 1/4] drm/edid: seek for available CEA block from specific EDID block index

2022-03-02 Thread Lee Shawn C
drm_find_cea_extension() always look for a top level CEA block. Pass
ext_index from caller then this function to search next available
CEA ext block from a specific EDID block pointer.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 42 ++
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a504542238ed..375e70d9de86 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3353,16 +3353,14 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid)
+static const u8 *drm_find_cea_extension(const struct edid *edid, int 
*ext_index)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
-   int ext_index = 0;
 
-   /* Look for a top level CEA extension block */
-   /* FIXME: make callers iterate through multiple CEA ext blocks? */
-   cea = drm_find_edid_extension(edid, CEA_EXT, &ext_index);
+   /* Look for a CEA extension block from ext_index */
+   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
if (cea)
return cea;
 
@@ -3643,10 +3641,10 @@ add_alternate_cea_modes(struct drm_connector 
*connector, struct edid *edid)
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *tmp;
LIST_HEAD(list);
-   int modes = 0;
+   int modes = 0, ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid))
+   if (!drm_find_cea_extension(edid, &ext_index))
return 0;
 
/*
@@ -4321,11 +4319,11 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea = drm_find_cea_extension(edid);
-   const u8 *db, *hdmi = NULL, *video = NULL;
+   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
u8 dbl, hdmi_len, video_len = 0;
-   int modes = 0;
+   int modes = 0, ext_index = 0;
 
+   cea = drm_find_cea_extension(edid, &ext_index);
if (cea && cea_revision(cea) >= 3) {
int i, start, end;
 
@@ -4562,7 +4560,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
uint8_t *eld = connector->eld;
const u8 *cea;
const u8 *db;
-   int total_sad_count = 0;
+   int total_sad_count = 0, ext_index = 0;
int mnl;
int dbl;
 
@@ -4571,7 +4569,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, &ext_index);
if (!cea) {
DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
return;
@@ -4655,11 +4653,11 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
  */
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
 {
-   int count = 0;
+   int count = 0, ext_index = 0;
int i, start, end, dbl;
const u8 *cea;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, &ext_index);
if (!cea) {
DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
return 0;
@@ -4717,11 +4715,11 @@ EXPORT_SYMBOL(drm_edid_to_sad);
  */
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
 {
-   int count = 0;
+   int count = 0, ext_index = 0;
int i, start, end, dbl;
const u8 *cea;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, &ext_index);
if (!cea) {
DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
return 0;
@@ -4814,9 +4812,9 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
 {
const u8 *edid_ext;
int i;
-   int start_offset, end_offset;
+   int start_offset, end_offset, ext_index = 0;
 
-   edid_ext = drm_find_cea_extension(edid);
+   edid_ext = drm_find_cea_extension(edid, &ext_index);
if (!edid_ext)
return false;
 
@@ -4853,9 +4851,9 @@ bool drm_detect_monitor_audio(struct edid *edid)
const u8 *edid_ext;
int i, j;
bool has_audio = false;
-   int start_offset, end_offset;
+   int start_offset, end_offset, ext_index = 0;
 
-   edid_ext = drm_find_cea_extension(edid);
+   edid_ext = drm_find_cea_extension(edid, &ext_index);
if (!edid_ext)
goto end;
 
@@ -5177,9 +5175,9 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
 {
struct drm_display_info *info = &connector->display_info;
const u8 *edid_ext;
-  

[v3 2/4] drm/edid: parse multiple CEA extension block

2022-03-02 Thread Lee Shawn C
Try to find and parse more CEA ext blocks if edid->extensions
is greater than one.

v2: split prvious patch to two. And do CEA block parsing
in this one.
v3: simplify this patch based on previous change.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 36 ++--
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 375e70d9de86..c4a47465ba76 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4319,16 +4319,24 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
-   u8 dbl, hdmi_len, video_len = 0;
+   const u8 *cea, *db;
+   u8 dbl, hdmi_len;
int modes = 0, ext_index = 0;
+   int i, start, end;
 
-   cea = drm_find_cea_extension(edid, &ext_index);
-   if (cea && cea_revision(cea) >= 3) {
-   int i, start, end;
+   for (;;) {
+   const u8 *hdmi = NULL, *video = NULL;
+   u8 video_len = 0;
+
+   cea = drm_find_cea_extension(edid, &ext_index);
+   if (!cea)
+   break;
+
+   if (cea_revision(cea) < 3)
+   continue;
 
if (cea_db_offsets(cea, &start, &end))
-   return 0;
+   continue;
 
for_each_cea_db(cea, i, start, end) {
db = &cea[i];
@@ -4350,15 +4358,15 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
  dbl - 1);
}
}
-   }
 
-   /*
-* We parse the HDMI VSDB after having added the cea modes as we will
-* be patching their flags when the sink supports stereo 3D.
-*/
-   if (hdmi)
-   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
-   video_len);
+   /*
+* We parse the HDMI VSDB after having added the cea modes as 
we will
+* be patching their flags when the sink supports stereo 3D.
+*/
+   if (hdmi)
+   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, 
video,
+   video_len);
+   }
 
return modes;
 }
-- 
2.31.1



[v3 3/4] drm/edid: read HF-EEODB ext block

2022-03-02 Thread Lee Shawn C
According to HDMI 2.1 spec.

"The HDMI Forum EDID Extension Override Data Block (HF-EEODB)
is utilized by Sink Devices to provide an alternate method to
indicate an EDID Extension Block count larger than 1, while
avoiding the need to present a VESA Block Map in the first
E-EDID Extension Block."

It is a mandatory for HDMI 2.1 protocol compliance as well.
This patch help to know how many HF_EEODB blocks report by sink
and read allo HF_EEODB blocks back.

v2: support to find CEA block, check EEODB block format, and return
available block number in drm_edid_read_hf_eeodb_blk_count().

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_connector.c |  8 +++-
 drivers/gpu/drm/drm_edid.c  | 71 +++--
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index a50c82bc2b2f..16011023c12e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid)
 {
struct drm_device *dev = connector->dev;
-   size_t size = 0;
+   size_t size = 0, hf_eeodb_blk_count;
int ret;
const struct edid *old_edid;
 
@@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
if (connector->override_edid)
return 0;
 
-   if (edid)
+   if (edid) {
size = EDID_LENGTH * (1 + edid->extensions);
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
+   if (hf_eeodb_blk_count)
+   size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
+   }
 
/* Set the display info, using edid if available, otherwise
 * resetting the values to defaults. This duplicates the work
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index c4a47465ba76..e5ac9ab0b9d0 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
 {
int i, j = 0, valid_extensions = 0;
u8 *edid, *new;
+   size_t hf_eeodb_blk_count;
struct edid *override;
 
override = drm_get_override_edid(connector);
@@ -2051,7 +2052,35 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
}
 
kfree(edid);
+   return (struct edid *)new;
+   }
+
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid 
*)edid);
+   if (hf_eeodb_blk_count >= 2) {
+   new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, 
GFP_KERNEL);
+   if (!new)
+   goto out;
edid = new;
+
+   valid_extensions = hf_eeodb_blk_count - 1;
+   for (j = 2; j <= hf_eeodb_blk_count; j++) {
+   u8 *block = edid + j * EDID_LENGTH;
+
+   for (i = 0; i < 4; i++) {
+   if (get_edid_block(data, block, j, EDID_LENGTH))
+   goto out;
+   if (drm_edid_block_valid(block, j, false, NULL))
+   break;
+   }
+
+   if (i == 4)
+   valid_extensions--;
+   }
+
+   if (valid_extensions != hf_eeodb_blk_count - 1) {
+   DRM_ERROR("Not able to retrieve proper EDID contain 
HF-EEODB data.\n");
+   goto out;
+   }
}
 
return (struct edid *)edid;
@@ -3315,15 +3344,17 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define VIDEO_BLOCK 0x02
 #define VENDOR_BLOCK0x03
 #define SPEAKER_BLOCK  0x04
-#define HDR_STATIC_METADATA_BLOCK  0x6
-#define USE_EXTENDED_TAG 0x07
-#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define HDR_STATIC_METADATA_BLOCK  0x06
+#define USE_EXTENDED_TAG   0x07
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
-#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
+#define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
 #define EDID_CEA_VCDB_QS   (1 << 6)
+#define HF_EEODB_LENGTH2
 
 /*
  * Search EDID for CEA extension block.
@@ -4273,9 +4304,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hdmi_forum_eeodb(const u8 *db)
+{
+   if (cea_db_tag(db) != USE_EXTENDED_TAG)
+   return false;
+
+   if (cea_db_payload_len(db) != HF_EEOD

[v3 4/4] drm/edid: parse HF-EEODB CEA extension block

2022-03-02 Thread Lee Shawn C
While adding CEA modes, try to get available EEODB block
number. Then based on it to parse numbers of ext blocks,
retrieve CEA information and add more CEA modes.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_displayid.c |  5 -
 drivers/gpu/drm/drm_edid.c  | 35 +++--
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 32da557b960f..dc649a9efaa2 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -37,7 +37,10 @@ static const u8 *drm_find_displayid_extension(const struct 
edid *edid,
  int *length, int *idx,
  int *ext_index)
 {
-   const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, 
ext_index);
+   const u8 *displayid = drm_find_edid_extension(edid,
+ DISPLAYID_EXT,
+ ext_index,
+ edid->extensions);
const struct displayid_header *base;
int ret;
 
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index e5ac9ab0b9d0..2b8ddc956ce2 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3360,23 +3360,23 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
  * Search EDID for CEA extension block.
  */
 const u8 *drm_find_edid_extension(const struct edid *edid,
- int ext_id, int *ext_index)
+ int ext_id, int *ext_index, int ext_blk_num)
 {
const u8 *edid_ext = NULL;
int i;
 
/* No EDID or EDID extensions */
-   if (edid == NULL || edid->extensions == 0)
+   if (edid == NULL || edid->extensions == 0 || *ext_index >= ext_blk_num)
return NULL;
 
/* Find CEA extension */
-   for (i = *ext_index; i < edid->extensions; i++) {
+   for (i = *ext_index; i < ext_blk_num; i++) {
edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
if (edid_ext[0] == ext_id)
break;
}
 
-   if (i >= edid->extensions)
+   if (i >= ext_blk_num)
return NULL;
 
*ext_index = i + 1;
@@ -3384,14 +3384,15 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid, int 
*ext_index)
+static const u8 *drm_find_cea_extension(const struct edid *edid,
+   int *ext_index, int ext_blk_num)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
 
/* Look for a CEA extension block from ext_index */
-   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
+   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index, ext_blk_num);
if (cea)
return cea;
 
@@ -3675,7 +3676,7 @@ add_alternate_cea_modes(struct drm_connector *connector, 
struct edid *edid)
int modes = 0, ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid, &ext_index))
+   if (!drm_find_cea_extension(edid, &ext_index, edid->extensions))
return 0;
 
/*
@@ -4327,7 +4328,7 @@ size_t drm_edid_read_hf_eeodb_blk_count(const struct edid 
*edid)
int i, start, end, ext_index = 0;
 
if (edid->extensions) {
-   cea = drm_find_cea_extension(edid, &ext_index);
+   cea = drm_find_cea_extension(edid, &ext_index, 
edid->extensions);
 
if (cea && !cea_db_offsets(cea, &start, &end))
for_each_cea_db(cea, i, start, end)
@@ -4386,12 +4387,16 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
u8 dbl, hdmi_len;
int modes = 0, ext_index = 0;
int i, start, end;
+   int ext_blk_num = drm_edid_read_hf_eeodb_blk_count(edid);
+
+   if (!ext_blk_num)
+   ext_blk_num = edid->extensions;
 
for (;;) {
const u8 *hdmi = NULL, *video = NULL;
u8 video_len = 0;
 
-   cea = drm_find_cea_extension(edid, &ext_index);
+   cea = drm_find_cea_extension(edid, &ext_index, ext_blk_num);
if (!cea)
break;
 
@@ -4640,7 +4645,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid, &ext_index);
+   cea = drm_find_cea_extension(edid, &ext_index, edid->extensions);
if (!cea) {
DRM_DEBUG_KMS("ELD: no CEA Extension foun

RE: [EXT] Re: [PATCH 1/9] dt-bindings: mxsfb: Add compatible for i.MX8MP

2022-03-02 Thread Robby Cai


>-Original Message-
>From: Lucas Stach 
>Sent: 2022年3月1日 21:19
>To: Adam Ford 
>Cc: Marek Vasut ; Ying Liu (OSS) ;
>dri-devel ; devicetree
>; Peng Fan ; Alexander Stein
>; Rob Herring ;
>Laurent Pinchart ; Sam Ravnborg
>; Robby Cai 
>Subject: [EXT] Re: [PATCH 1/9] dt-bindings: mxsfb: Add compatible for
>i.MX8MP
>
>Caution: EXT Email
>
>Am Dienstag, dem 01.03.2022 um 07:03 -0600 schrieb Adam Ford:
>> On Tue, Mar 1, 2022 at 5:05 AM Lucas Stach 
>wrote:
>> >
>> > Am Dienstag, dem 01.03.2022 um 11:19 +0100 schrieb Marek Vasut:
>> > > On 3/1/22 11:04, Lucas Stach wrote:
>> > >
>> > > Hi,
>> > >
>> > > [...]
>> > >
>> > > > > Given the two totally different IPs, I don't see bugs of IP
>> > > > > control logics should be fixed for both drivers. Naturally,
>> > > > > the two would diverge due to different HWs. Looking at Patch
>> > > > > 9/9, it basically squashes code to control LCDIFv3 into the
>> > > > > mxsfb drm driver with 'if/else' checks(barely no common
>> > > > > control code), which is hard to maintain and not able to achieve good
>scalability for both 'LCDIFv3'
>> > > > > and 'LCDIF'.
>> > > >
>> > > > I tend to agree with Liu here. Writing a DRM driver isn't that
>> > > > much boilerplate anymore with all the helpers we have available
>> > > > in the framework today.
>> > >
>> > > I did write a separate driver for this IP before I spent time
>> > > merging them into single driver, that's when I realized a single
>> > > driver is much better and discarded the separate driver idea.
>> > >
>> > > > The IP is so different from the currently supported LCDIF
>> > > > controllers that I think trying to support this one in the
>> > > > existing driver actually increases the chances to break
>> > > > something when modifying the driver in the future. Not everyone
>> > > > is able to test all LCDIF versions. My vote is on having a separate 
>> > > > driver
>for the i.MX8MP LCDIF.
>> > >
>> > > If you look at both controllers, it is clear it is still the LCDIF
>> > > behind, even the CSC that is bolted on would suggest that.
>> >
>> > Yes, but from a driver PoV what you care about is not really the
>> > hardware blocks used to implement something, but the programming
>> > model, i.e. the register interface exposed to software.
>> >
>> > >
>> > > I am also not happy when I look at the amount of duplication a
>> > > separate driver would create, it will be some 50% of the code that
>> > > would be just duplicated.
>> > >
>> > Yea, the duplicated code is still significant, as the HW itself is
>> > so simple. However, if you find yourself in the situation where
>> > basically every actual register access in the driver ends up being
>> > in a "if (some HW rev) ... " clause, i still think it would be
>> > better to have a separate driver, as the programming interface is just
>different.
>>
>> I tend to agree with Marek on this one.  We have an instance where the
>> blk-ctrl and the GPC driver between 8m, mini, nano, plus are close,
>> but different enough where each SoC has it's own set of tables and
>> some checks.   Lucas created the framework, and others adapted it for
>> various SoC's.  If there really is nearly 50% common code for the
>> LCDIF, why not either leave the driver as one or split the common code
>> into its own driver like lcdif-common and then have smaller drivers
>> that handle their specific variations.
>
>I don't know exactly how the standalone driver looks like, but I guess the
>overlap is not really in any real HW specific parts, but the common DRM
>boilerplate, so there isn't much point in creating a common lcdif driver.
>
>As you brought up the blk-ctrl as an example: I'm all for supporting slightly
>different hardware in the same driver, as long as the HW interface is close
>enough. But then I also opted for a separate 8MP blk-ctrl driver for those
>blk-ctrls that differ significantly from the others, as I think it would make 
>the
>common driver unmaintainable trying to support all the different variants in
>one driver.
>
>Regards,
>Lucas

LCDIF on i.MX8MP is a different IP which is borrowed from non-iMX series, 
although it's also called 'LCDIF'.
We prefer not mix these two series of IPs in one driver for ease of maintenance 
and extension.

Regards,
Robby   


[PATCH] video: fbdev: s3c-fb: fix platform_get_irq.cocci warning

2022-03-02 Thread Yihao Han
Remove dev_err() messages after platform_get_irq*() failures.
platform_get_irq() already prints an error.

Generated by: scripts/coccinelle/api/platform_get_irq.cocci

Signed-off-by: Yihao Han 
---
 drivers/video/fbdev/s3c-fb.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/video/fbdev/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c
index 208514054c23..3abbc5737c3b 100644
--- a/drivers/video/fbdev/s3c-fb.c
+++ b/drivers/video/fbdev/s3c-fb.c
@@ -1418,7 +1418,6 @@ static int s3c_fb_probe(struct platform_device *pdev)
 
sfb->irq_no = platform_get_irq(pdev, 0);
if (sfb->irq_no < 0) {
-   dev_err(dev, "failed to acquire irq resource\n");
ret = -ENOENT;
goto err_lcd_clk;
}
-- 
2.17.1



Re: [PATCH] drm/exynos: fimd: add BGR support for exynos4/5

2022-03-02 Thread Martin Jücker
Hi Inki,

On Tue, Mar 01, 2022 at 04:52:20PM +0900, Inki Dae wrote:
> Hi Martin,
> 
> 22. 2. 25. 18:33에 Martin Jücker 이(가) 쓴 글:
> > Hello Inki,
> > 
> > On Fri, Feb 25, 2022 at 12:52:56PM +0900, Inki Dae wrote:
> >> Hi Martin,
> >>
> >> 22. 2. 25. 08:27에 Martin Jücker 이(가) 쓴 글:
> >>> Hello Inki,
> >>>
> >>> On Thu, Feb 24, 2022 at 10:41:04AM +0900, Inki Dae wrote:
>  Hi Martin.
> 
>  I found that exynos4 and 5 data sheet include documented same register.
>  RGB_ORDER_E field of VIDCONx registers will do same thing.
> >>>
> >>> If I read the manual correctly, this register combined with the
> >>> RGB_ORDER_O makes it possible to map the whole RGB interface output to a
> >>> different order. What my patch provides is a way to configure each
> >>> hardware plane separately while maintaining a consistent output on the
> >>> RGB interface.
> >>>
> >>
> >> Understood. Your patch will allow BGR pixel order per a plane. Seems to be 
> >> useful because a framebuffer with BGR pixel format can be displayed on 
> >> screen without any color space conversion. :)
> >>
> >>> Implementing the RGB_ORDER_O and E would need some logic to make sure
> >>> that all planes are always using the same RGB order.
> >>>
> 
>  I'm not sure whether the use of undocumented register is safe or not - 
>  maybe some HW bug exists.
> >>>
> >>> I see, that makes sense. Would it be possible then to introduce a new
> >>> compatible, e.g. samsung,exynos4210-fimd-ext which can be used on tested
> >>
> >> Seems providing a new compatible is not a good idea.

Thinking about it afterwards, I fully agree :)

> >>
> >>> devices? I know that some other Galaxy Note and S devices with the
> >>> exynos4 chip have the same problem (and solution).
> >>
> >> Could you give me more details about the same problem and its solution on 
> >> the devices?
> >> It would be useful for us to decide the upstream direction.
> >>
> >> If necessary then we may need to contact HW engineer for clarity.
> > 
> > Here is my current understanding of the situation:
> > 
> > The issue is related to Android and a recovery image having conflicting
> > pixel formats on the same device. There is a solution in Replicant[1]
> > for this using parameters for the fimd driver to force the pixel format
> > to RGB or BGR. It's using the PNRMODE register on VIDCON0, but this
> > solution needs two separate kernels to be built to add the parameter as
> > the boot loader is not adjustable.
> > 
> > This was also discussed in dri-devel irc and it was proposed to expose
> > both formats and fail the atomic commit if userspace tried to use both
> > RGB and BGR formats at the same time. With this approach there should be
> > something on the screen but it might happen that some users can't deal
> > with the failing commits as it's rather difficult to find the cause and
> > fix it on the go.
> 
> Thanks for sharing.
> 
> > 
> > After that I accidentally discovered this undocumented register while
> > reading the old vendor sources and it seems that it fixes all the
> 
> Are the old vendor sources using this undocumented register? If so then the 
> use of the register would be safe.

Here are some examples for vendor sources collected by Krzysztof that
make use of this register on several Exynos4/5 devices.

* Galaxy S4 (Exynos 5410) [1]
* Samsung Galaxy Tab S10.5 (Exynos 5420) [2]
* Galaxy Note 10.1 (Exynos 4412) [3]
* Galaxy S2/S3 (Exynos 4210/4412) [4]

> 
> > issues. At least if there are no HW bugs as you mentioned.
> 
> I will try to contact HW engineer and check if no problem.

If you could get definitive confirmation, that would be great of course.

Thank you for your effort.

Kind Regards
Martin

[1] 
https://github.com/krzk/linux-vendor-backup/blob/mokee/android-3.4-samsung-galaxy-s4-i9500-exynos5410/drivers/video/s3c-fb.c#L1127
[2] 
https://github.com/krzk/linux-vendor-backup/blob/mokee/android-3.4-samsung-galaxy-tab-s-10.5-sm-t805-exynos5420/drivers/video/s3c-fb.c#L1533
[3] 
https://github.com/krzk/linux-vendor-backup/blob/samsung/galaxy-note-tab-10.1-2012-gt-n8010-p4note-exynos4412-dump/drivers/video/samsung/s3cfb_ops.c#L1594
[4] 
https://github.com/krzk/linux-vendor-backup/blob/lineage/android-samsung-galaxy-i9100-i9300-exynos4210-exynos4412/drivers/video/samsung/s3cfb_ops.c#L1600

>
> Thanks,
> Inki Dae
> 
> > 
> 
> 
> 
> > Kind Regards
> > Martin
> > 
> > [1] 
> > https://protect2.fireeye.com/v1/url?k=d515db34-b4683348-d514507b-74fe485cc33c-0ee001ffdcafd932&q=1&e=851ccfed-b6fa-4794-8989-27ef28bc7ac6&u=https%3A%2F%2Fgit.replicant.us%2Freplicant-next%2Fkernel_replicant_linux%2Fcommit%2F%3Fh%3Dreplicant-11%26id%3Dcc5a0615b40cd5ede1eb87a60daa50333701a135
> > 
> >>
> >> Thanks,
> >> Inki Dae
> >>
> >>>
> 
>  Anyway, I'd like to recommend you to use documented register only.
> 
>  Sorry for late and thanks,
>  Inki Dae
> >>>
> >>> Kind Regards
> >>> Martin
> >>>
> 
>  22. 1. 30. 07:01에 Martin Jücker 이(가) 쓴 글:
> > In the downst

Re: [PATCH v3 00/21] DEPT(Dependency Tracker)

2022-03-02 Thread Hyeonggon Yoo
On Mon, Feb 28, 2022 at 06:56:39PM +0900, Byungchul Park wrote:
> I didn't want to bother you so I was planning to send the next spin
> after making more progress. However, PATCH v2 reports too many false
> positives because Dept tracked the bit_wait_table[] wrong way - I
> apologize for that. So I decided to send PATCH v3 first before going
> further for those who want to run Dept for now.
> 
> There might still be some false positives but not overwhelming.
>

Hello Byungchul, I'm running DEPT v3 on my system
and I see report below.

Looking at the kmemleak code and comment, I think
kmemleak tried to avoid lockdep recursive warning
but detected by DEPT?

===
DEPT: Circular dependency has been detected.
5.17.0-rc1+ #1 Tainted: GW
---
summary
---
*** AA DEADLOCK ***

context A
[S] __raw_spin_lock_irqsave(&object->lock:0)
[W] _raw_spin_lock_nested(&object->lock:0)
[E] spin_unlock(&object->lock:0)

[S]: start of the event context
[W]: the wait blocked
[E]: the event not reachable
---
context A's detail
---
context A
[S] __raw_spin_lock_irqsave(&object->lock:0)
[W] _raw_spin_lock_nested(&object->lock:0)
[E] spin_unlock(&object->lock:0)

[S] __raw_spin_lock_irqsave(&object->lock:0):
[] scan_gray_list+0x84/0x13c
stacktrace:
  dept_ecxt_enter+0x88/0xf4
  _raw_spin_lock_irqsave+0xf0/0x1c4
  scan_gray_list+0x84/0x13c
  kmemleak_scan+0x2d8/0x54c
  kmemleak_scan_thread+0xac/0xd4
  kthread+0xd4/0xe4
  ret_from_fork+0x10/0x20

[E] spin_unlock(&object->lock:0):
[] scan_block+0x60/0x128
---
information that might be helpful
---
CPU: 1 PID: 38 Comm: kmemleak Tainted: GW 5.17.0-rc1+ #1
Hardware name: linux,dummy-virt (DT)
Call trace:
 dump_backtrace.part.0+0x9c/0xc4
 show_stack+0x14/0x28
 dump_stack_lvl+0x9c/0xcc
 dump_stack+0x14/0x2c
 print_circle+0x2d4/0x438
 cb_check_dl+0x44/0x70
 bfs+0x60/0x168
 add_dep+0x88/0x11c
 add_wait+0x2d0/0x2dc
 __dept_wait+0x8c/0xa4
 dept_wait+0x6c/0x88
 _raw_spin_lock_nested+0xa8/0x1b0
 scan_block+0xb4/0x128
 scan_gray_list+0xc4/0x13c
 kmemleak_scan+0x2d8/0x54c
 kmemleak_scan_thread+0xac/0xd4
 kthread+0xd4/0xe4
 ret_from_fork+0x10/0x20

> ---
> 
> Hi Linus and folks,
> 
> I've been developing a tool for detecting deadlock possibilities by
> tracking wait/event rather than lock(?) acquisition order to try to
> cover all synchonization machanisms. It's done on v5.17-rc1 tag.
> 
> https://github.com/lgebyungchulpark/linux-dept/commits/dept1.14_on_v5.17-rc1
>
[...]
> Benifit:
> 
>   0. Works with all lock primitives.
>   1. Works with wait_for_completion()/complete().
>   2. Works with 'wait' on PG_locked.
>   3. Works with 'wait' on PG_writeback.
>   4. Works with swait/wakeup.
>   5. Works with waitqueue.
>   6. Multiple reports are allowed.
>   7. Deduplication control on multiple reports.
>   8. Withstand false positives thanks to 6.
>   9. Easy to tag any wait/event.
> 
> Future work:
> 
>   0. To make it more stable.
>   1. To separates Dept from Lockdep.
>   2. To improves performance in terms of time and space.
>   3. To use Dept as a dependency engine for Lockdep.
>   4. To add any missing tags of wait/event in the kernel.
>   5. To deduplicate stack trace.
> 
> How to interpret reports:
> 
>   1. E(event) in each context cannot be triggered because of the
>  W(wait) that cannot be woken.
>   2. The stack trace helping find the problematic code is located
>  in each conext's detail.
> 
> Thanks,
> Byungchul
> 
> ---
> 
> Changes from v2:
> 
>   1. Disable Dept on bit_wait_table[] in sched/wait_bit.c
>  reporting a lot of false positives, which is my fault.
>  Wait/event for bit_wait_table[] should've been tagged in a
>  higher layer for better work, which is a future work.
>  (feedback from Jan Kara)
>   2. Disable Dept on crypto_larval's completion to prevent a false
>  positive.
> 
> Changes from v1:
> 
>   1. Fix coding style and typo. (feedback from Steven)
>   2. Distinguish each work context from another in workqueue.
>   3. Skip checking lock acquisition with nest_lock, which is about
>  correct lock usage that should be checked by Lockdep.
> 
> Changes from RFC:
> 
>   1. Prevent adding a wait tag at prepare_to_wait() but __schedule().
>  (feedback from Linus and Matthew)
>   2. Use try version at lockdep_acquire_cpus_lock() annotation.
>   3. Distinguish each syscall context from another.
[ ... ] 

-- 
Thank you, You are awesome!
Hyeonggon :-)


Re: [PATCH v3 00/21] DEPT(Dependency Tracker)

2022-03-02 Thread Hyeonggon Yoo
On Wed, Mar 02, 2022 at 04:36:38AM +, Hyeonggon Yoo wrote:
> On Mon, Feb 28, 2022 at 06:56:39PM +0900, Byungchul Park wrote:
> > I didn't want to bother you so I was planning to send the next spin
> > after making more progress. However, PATCH v2 reports too many false
> > positives because Dept tracked the bit_wait_table[] wrong way - I
> > apologize for that. So I decided to send PATCH v3 first before going
> > further for those who want to run Dept for now.
> > 
> > There might still be some false positives but not overwhelming.
> >
> 
> Hello Byungchul, I'm running DEPT v3 on my system
> and I see report below.
> 
> Looking at the kmemleak code and comment, I think
> kmemleak tried to avoid lockdep recursive warning
> but detected by DEPT?
>

Forgot to include another warning caused by DEPT.

And comment below might be useful for debugging:

in kmemleak.c:
  43  * Locks and mutexes are acquired/nested in the following order:
  44  *
  45  *   scan_mutex [-> object->lock] -> kmemleak_lock -> other_object->lock 
(SINGLE_DEPTH_NESTING)
  46  *
  47  * No kmemleak_lock and object->lock nesting is allowed outside scan_mutex
  48  * regions.

===
DEPT: Circular dependency has been detected.
5.17.0-rc1+ #1 Tainted: GW
---
summary
---
*** DEADLOCK ***

context A
[S] __raw_spin_lock_irqsave(&object->lock:0)
[W] __raw_spin_lock_irqsave(kmemleak_lock:0)
[E] spin_unlock(&object->lock:0)

context B
[S] __raw_spin_lock_irqsave(kmemleak_lock:0)
[W] _raw_spin_lock_nested(&object->lock:0)
[E] spin_unlock(kmemleak_lock:0)

[S]: start of the event context
[W]: the wait blocked
[E]: the event not reachable

---
context A's detail
---
context A
[S] __raw_spin_lock_irqsave(&object->lock:0)
[W] __raw_spin_lock_irqsave(kmemleak_lock:0)
[E] spin_unlock(&object->lock:0)

[S] __raw_spin_lock_irqsave(&object->lock:0):
[] scan_gray_list+0x84/0x13c
stacktrace:
  dept_ecxt_enter+0x88/0xf4
  _raw_spin_lock_irqsave+0xf0/0x1c4
  scan_gray_list+0x84/0x13c
  kmemleak_scan+0x2d8/0x54c
  kmemleak_scan_thread+0xac/0xd4
  kthread+0xd4/0xe4
  ret_from_fork+0x10/0x20

[W] __raw_spin_lock_irqsave(kmemleak_lock:0):
[] scan_block+0x3c/0x128
stacktrace:
  __dept_wait+0x8c/0xa4
  dept_wait+0x6c/0x88
  _raw_spin_lock_irqsave+0xb8/0x1c4
  scan_block+0x3c/0x128
  scan_gray_list+0xc4/0x13c
  kmemleak_scan+0x2d8/0x54c
  kmemleak_scan_thread+0xac/0xd4
  kthread+0xd4/0xe4
  ret_from_fork+0x10/0x20

[E] spin_unlock(&object->lock:0):
[] scan_block+0x60/0x128

---
context B's detail
---
context B
[S] __raw_spin_lock_irqsave(kmemleak_lock:0)
[W] _raw_spin_lock_nested(&object->lock:0)
[E] spin_unlock(kmemleak_lock:0)

[S] __raw_spin_lock_irqsave(kmemleak_lock:0):
[] scan_block+0x3c/0x128
stacktrace:
  dept_ecxt_enter+0x88/0xf4
  _raw_spin_lock_irqsave+0xf0/0x1c4
  scan_block+0x3c/0x128
  kmemleak_scan+0x19c/0x54c
  kmemleak_scan_thread+0xac/0xd4
  kthread+0xd4/0xe4
  ret_from_fork+0x10/0x20

[W] _raw_spin_lock_nested(&object->lock:0):
[] scan_block+0xb4/0x128
stacktrace:
  dept_wait+0x74/0x88
  _raw_spin_lock_nested+0xa8/0x1b0
  scan_block+0xb4/0x128
  kmemleak_scan+0x19c/0x54c
  kmemleak_scan_thread+0xac/0xd4
  kthread+0xd4/0xe4
  ret_from_fork+0x10/0x20
[E] spin_unlock(kmemleak_lock:0):
[] scan_block+0x60/0x128
stacktrace:
  dept_event+0x7c/0xfc
  _raw_spin_unlock_irqrestore+0x8c/0x120
  scan_block+0x60/0x128
  kmemleak_scan+0x19c/0x54c
  kmemleak_scan_thread+0xac/0xd4
  kthread+0xd4/0xe4
  ret_from_fork+0x10/0x20
---
information that might be helpful
---
CPU: 1 PID: 38 Comm: kmemleak Tainted: GW 5.17.0-rc1+ #1
Hardware name: linux,dummy-virt (DT)
Call trace:
 dump_backtrace.part.0+0x9c/0xc4
 show_stack+0x14/0x28
 dump_stack_lvl+0x9c/0xcc
 dump_stack+0x14/0x2c
 print_circle+0x2d4/0x438
 cb_check_dl+0x6c/0x70
 bfs+0xc0/0x168
 add_dep+0x88/0x11c
 add_wait+0x2d0/0x2dc
 __dept_wait+0x8c/0xa4
 dept_wait+0x6c/0x88
 _raw_spin_lock_irqsave+0xb8/0x1c4
 scan_block+0x3c/0x128
 scan_gray_list+0xc4/0x13c
 kmemleak_scan+0x2d8/0x54c
 kmemleak_scan_thread+0xac/0xd4
 kthread+0xd4/0xe4
 ret_from_fork+0x10/0x20

> ===
> DEPT: Circular dependency has been detected.
> 5.17.0-rc1+ #1 Tainted: GW
> ---
> summary
> ---
> *** AA DEADLOCK ***
> 
> context A
> [S] __raw_spin_lock_

Re: [PATCH 5/5] spi: make remove callback a void function

2022-03-02 Thread Pavel Machek
Hi!

> The value returned by an spi driver's remove function is mostly ignored.
> (Only an error message is printed if the value is non-zero that the
> error is ignored.)
> 
> So change the prototype of the remove function to return no value. This
> way driver authors are not tempted to assume that passing an error to
> the upper layer is a good idea. All drivers are adapted accordingly.
> There is no intended change of behaviour, all callbacks were prepared to
> return 0 before.

Acked-by: Pavel Machek 
Pavel
-- 
http://www.livejournal.com/~pavelmachek


signature.asc
Description: Digital signature


[PATCH] drm/sprd: fix platform_get_irq.cocci warning

2022-03-02 Thread Yihao Han
Remove dev_err() messages after platform_get_irq*() failures.
platform_get_irq() already prints an error.

Generated by: scripts/coccinelle/api/platform_get_irq.cocci

Signed-off-by: Yihao Han 
---
 drivers/gpu/drm/sprd/sprd_dpu.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/sprd/sprd_dpu.c b/drivers/gpu/drm/sprd/sprd_dpu.c
index 06a3414ee43a..328ca56695cd 100644
--- a/drivers/gpu/drm/sprd/sprd_dpu.c
+++ b/drivers/gpu/drm/sprd/sprd_dpu.c
@@ -797,10 +797,8 @@ static int sprd_dpu_context_init(struct sprd_dpu *dpu,
}
 
ctx->irq = platform_get_irq(pdev, 0);
-   if (ctx->irq < 0) {
-   dev_err(dev, "failed to get dpu irq\n");
+   if (ctx->irq < 0)
return ctx->irq;
-   }
 
/* disable and clear interrupts before register dpu IRQ. */
writel(0x00, ctx->base + REG_DPU_INT_EN);
-- 
2.17.1



Re: [PATCH v7, 04/15] media: mtk-vcodec: Read max resolution from dec_capability

2022-03-02 Thread Przemysław Drozdowski



MSM8960: gpu/drm/dp/drm_dp.c:59:27: warning: array subscript 10 is outside, array bounds of 'const u8[6]'

2022-03-02 Thread Rudraksha Gupta

Hi all,


I am getting this warning when compiling the kernel for the MSM8960 with 
this defconfig: 
https://raw.githubusercontent.com/apq8064-mainline/linux/qcom-apq8064-next/arch/arm/configs/qcom_apq8064_defconfig



Warning:

../drivers/gpu/drm/dp/drm_dp.c: In function 
'drm_dp_get_adjust_request_post_cursor':
../drivers/gpu/drm/dp/drm_dp.c:59:27: warning: array subscript 10 is 
outside array bounds of 'const u8[6]' {aka 'const unsigned char[6]'} 
[-Warray-bounds]

   59 | return link_status[r - DP_LANE0_1_STATUS];
  |    ~~~^~~
../drivers/gpu/drm/dp/drm_dp.c:210:51: note: while referencing 'link_status'
  210 | u8 drm_dp_get_adjust_request_post_cursor(const u8 
link_status[DP_LINK_STATUS_SIZE],

  | ~^~~~



[Bug 215648] amdgpu: Changing monitor configuration (plug/unplug/wake from DPMS) causes kernel panic

2022-03-02 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215648

--- Comment #2 from Philipp Riederer (pr_ker...@tum.fail) ---
Hey,

this is the log I could recover:

> <4>[   70.829010] RSP: 0018:ad060ad67838 EFLAGS: 0202
> <4>[   70.829013] RAX:  RBX: 92c82ff28000 RCX:
> 01f5
> <4>[   70.829014] RDX: c2fc3970 RSI: c3047f09 RDI:
> 
> <4>[   70.829014] RBP: 0012 R08:  R09:
> ad060ad67610
> <4>[   70.829015] R10: ad060ad67608 R11: 9b743bc8 R12:
> 92c827b30c00
> <4>[   70.829016] R13: 92c7e0b35000 R14: 92c82c8c R15:
> 92c82c8c0b58
> <4>[   70.829017] FS:  () GS:92cabf90()
> knlGS:
> <4>[   70.829018] CS:  0010 DS:  ES:  CR0: 80050033
> <4>[   70.829018] CR2: 7f2afe48ef20 CR3: 00014a5b4000 CR4:
> 00350ee0
> <0>[   70.829020] Kernel panic - not syncing: Fatal exception in interrupt
> <0>[   70.829047] Kernel Offset: 0x1900 from 0x8100
> (relocation range: 0x8000-0xbfff)
> <4>[   70.741431] ---[ end trace d042cf4ec67f5116 ]---
> <4>[   70.829001] RIP: 0010:kgdb_breakpoint+0x10/0x20
> <4>[   70.829009] Code: c0 c3 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 31 c0 c3
> 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 f0 ff 05 fc f9 f3 01 0f ae f8 cc <0f>
> ae f8 f0 ff 0d ee f9 f3 01 c3 0f 1f 44 00 00 0f 1f 44 00 00 48
> <4>[   70.702654]  videodev snd_hda_core ecdh_generic drm_kms_helper ecc
> snd_hwdep cdc_acm joydev mc thinkpad_acpi sp5100_tco snd_rn_pci_acp3x
> serio_raw efi_pstore k10temp cfg80211 snd_pcm i2c_piix4 nvram cec rtsx_pci
> snd_pci_acp3x ccp snd_timer rc_core ipmi_devintf ledtrig_audio ucsi_acpi
> platform_profile mfd_core ipmi_msghandler typec_ucsi snd roles mac_hid typec
> soundcore rfkill wmi video i2c_designware_platform i2c_scmi pinctrl_amd
> amd_pmc i2c_designware_core acpi_cpufreq vboxnetadp(OE) vboxnetflt(OE) nfsd
> auth_rpcgss vboxdrv(OE) drm nfs_acl lockd grace backlight fuse i2c_core
> configfs sunrpc bpf_preload efivarfs zfs(POE) zunicode(POE) zzstd(OE)
> zlua(OE) zavl(POE) icp(POE) crc32_pclmul crc32c_intel zcommon(POE)
> znvpair(POE) spl(OE) xhci_pci xhci_pci_renesas aesni_intel r8169 crypto_simd
> realtek cryptd xhci_hcd mdio_devres ehci_pci libphy ehci_hcd
> <4>[   70.702619]  ? set_kthread_struct+0x40/0x40
> <4>[   70.702620]  ret_from_fork+0x22/0x30
> <4>[   70.702623]  
> <4>[   70.702623] Modules linked in: ccm xt_mark xt_comment tun xt_CHECKSUM
> xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 ip6table_mangle
> ip6table_nat ip6table_filter ip6_tables iptable_mangle iptable_nat nf_nat
> nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c iptable_filter ip_tables
> bridge stp llc cmac algif_skcipher bnep intel_rapl_msr intel_rapl_common
> snd_acp3x_rn snd_soc_dmic snd_acp3x_pdm_dma snd_soc_core snd_compress
> rtsx_pci_sdmmc edac_mce_amd snd_pcm_dmaengine mmc_core ac97_bus wmi_bmof
> kvm_amd snd_ctl_led iwlmvm snd_hda_codec_realtek amdgpu mac80211
> snd_hda_codec_generic kvm snd_hda_codec_hdmi uvcvideo btusb libarc4 btrtl
> irqbypass btbcm drm_ttm_helper cdc_ether snd_hda_intel btintel
> videobuf2_vmalloc crct10dif_pclmul videobuf2_memops ttm snd_intel_dspcfg
> snd_usb_audio usbnet snd_intel_sdw_acpi ghash_clmulni_intel videobuf2_v4l2
> iommu_v2 snd_usbmidi_lib gpu_sched bluetooth iwlwifi snd_hda_codec r8152
> videobuf2_common snd_rawmidi rapl i2c_algo_bit mii snd_seq_device
> <4>[   70.702134]  ? dc_validate_global_state+0x321/0x3c0 [amdgpu]
> <4>[   70.702259]  ? dm_plane_helper_prepare_fb+0x231/0x2b0 [amdgpu]
> <4>[   70.702382]  ? __cond_resched+0x16/0x40
> <4>[   70.702385]  ? __wait_for_common+0x3b/0x160
> <4>[   70.702386]  ? __raw_callee_save___native_queued_spin_unlock+0x11/0x1e
> <4>[   70.702390]  commit_tail+0x94/0x120 [drm_kms_helper]
> <4>[   70.702401]  drm_atomic_helper_commit+0x113/0x140 [drm_kms_helper]
> <4>[   70.702412]  drm_client_modeset_commit_atomic+0x1e4/0x220 [drm]
> <4>[   70.702430]  drm_client_modeset_commit_locked+0x56/0x150 [drm]
> <4>[   70.702444]  drm_client_modeset_commit+0x24/0x40 [drm]
> <4>[   70.702458]  drm_fb_helper_set_par+0xa5/0xd0 [drm_kms_helper]
> <4>[   70.702468]  drm_fb_helper_hotplug_event.part.0+0xa8/0xc0
> [drm_kms_helper]
> <4>[   70.702476]  drm_kms_helper_hotplug_event+0x26/0x30 [drm_kms_helper]
> <4>[   70.702486]  handle_hpd_irq+0x12b/0x160 [amdgpu]
> <4>[   70.702611]  process_one_work+0x1f1/0x390
> <4>[   70.702614]  worker_thread+0x53/0x3e0
> <4>[   70.702615]  ? process_one_work+0x390/0x390
> <4>[   70.702617]  kthread+0x127/0x150
> <4>[   70.701096] RBP: 0012 R08:  R09:
> ad060ad67610
> <4>[   70.701096] R10: ad060ad67608 R11: 9b743bc8 R12:
> 92c827b30c00
> <4>[   70.701097] R13: 92c7e0b35000 R14: 92c82c8c R15:
> 92c82c8c0b58
> <4>[   70.701098] FS:  () GS:92cabf90()
> knlGS:
> 

Re: [PATCH v1,2/3] drm/mediatek: Add TOPCKGEN select mux control dpi_clk

2022-03-02 Thread AngeloGioacchino Del Regno

Il 25/02/22 10:53, xinlei@mediatek.com ha scritto:

From: Xinlei Lee 

Dpi_clk is controlled by the mux selected
by TOPCKGEN and APMIXEDSYS can support small resolution.

Signed-off-by: Xinlei Lee 


Hello Xinlei,

as it was pointed out by reviewers in the MT8195 DisplayPort series, that is
adding the same logic that you are proposing in this patch, the clock parent
selection should be performed by the clock drivers, I'd say in the callback
.set_rate_and_parent(), and not by the mtk_dpi driver.

Please fix this in the proper drivers (clocks!) instead.

Thanks,
Angelo


---
  drivers/gpu/drm/mediatek/mtk_dpi.c | 38 ++
  1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..bad686817e29 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -63,6 +63,14 @@ enum mtk_dpi_out_color_format {
MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
  };
  
+enum TVDPLL_CLK {

+   TVDPLL_PLL = 0,
+   TVDPLL_D2 = 2,
+   TVDPLL_D4 = 4,
+   TVDPLL_D8 = 8,
+   TVDPLL_D16 = 16,
+};
+
  struct mtk_dpi {
struct drm_encoder encoder;
struct drm_bridge bridge;
@@ -73,6 +81,7 @@ struct mtk_dpi {
struct clk *engine_clk;
struct clk *pixel_clk;
struct clk *tvd_clk;
+   struct clk *pclk_src[5];
int irq;
struct drm_display_mode mode;
const struct mtk_dpi_conf *conf;
@@ -459,6 +468,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
struct videomode vm = { 0 };
unsigned long pll_rate;
unsigned int factor;
+   struct clk *clksrc = NULL;
  
  	/* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */

factor = dpi->conf->cal_factor(mode->clock);
@@ -473,11 +483,26 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
  
  	vm.pixelclock = pll_rate / factor;

if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
-   (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
-   clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
-   else
-   clk_set_rate(dpi->pixel_clk, vm.pixelclock);
+   (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
+   if (factor == 8)
+   clksrc = dpi->pclk_src[2];
+   else if (factor == 4)
+   clksrc = dpi->pclk_src[1];
+   else
+   clksrc = dpi->pclk_src[1];
+   }
+   else {
+   if (factor == 8)
+   clksrc = dpi->pclk_src[3];
+   else if (factor == 4)
+   clksrc = dpi->pclk_src[2];
+   else
+   clksrc = dpi->pclk_src[2];
+   }
  
+	clk_prepare_enable(dpi->pixel_clk);

+   clk_set_parent(dpi->pixel_clk, clksrc);
+   clk_disable_unprepare(dpi->pixel_clk);
  
  	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
  
@@ -893,6 +918,11 @@ static int mtk_dpi_probe(struct platform_device *pdev)

return ret;
}
  
+	dpi->pclk_src[1] = devm_clk_get_optional(dev, "tvdpll_d2");

+   dpi->pclk_src[2] = devm_clk_get_optional(dev, "tvdpll_d4");
+   dpi->pclk_src[3] = devm_clk_get_optional(dev, "tvdpll_d8");
+   dpi->pclk_src[4] = devm_clk_get_optional(dev, "tvdpll_d16");
+
dpi->irq = platform_get_irq(pdev, 0);
if (dpi->irq <= 0)
return -EINVAL;




Re: [PATCH] drm/panfrost: cleanup comments

2022-03-02 Thread Steven Price
On 01/03/2022 12:43, t...@redhat.com wrote:
> From: Tom Rix 
> 
> For spdx
> change tab to space delimiter
> Use // for *.c
> 
> Replacements
> commited to committed, use multiline comment style
> regsiters to registers
> initialze to initialize
> 
> Signed-off-by: Tom Rix 

Thanks, most of the changes look reasonable (although I've never
understood the reason for using // for SPDX comments), but there's one
below that I think needs rethinking.

> ---
>  drivers/gpu/drm/panfrost/panfrost_drv.c  | 2 +-
>  drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c | 2 +-
>  drivers/gpu/drm/panfrost/panfrost_issues.h   | 6 --
>  drivers/gpu/drm/panfrost/panfrost_mmu.c  | 2 +-
>  drivers/gpu/drm/panfrost/panfrost_regs.h | 2 +-
>  5 files changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
> b/drivers/gpu/drm/panfrost/panfrost_drv.c
> index 96bb5a4656278..94b6f0a19c83a 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> @@ -562,7 +562,7 @@ static int panfrost_probe(struct platform_device *pdev)
>  
>   pfdev->coherent = device_get_dma_attr(&pdev->dev) == DEV_DMA_COHERENT;
>  
> - /* Allocate and initialze the DRM device. */
> + /* Allocate and initialize the DRM device. */
>   ddev = drm_dev_alloc(&panfrost_drm_driver, &pdev->dev);
>   if (IS_ERR(ddev))
>   return PTR_ERR(ddev);
> diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c 
> b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
> index b0142341e2235..77e7cb6d1ae3b 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
> @@ -1,4 +1,4 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> +// SPDX-License-Identifier: GPL-2.0
>  /* Copyright (C) 2019 Arm Ltd.
>   *
>   * Based on msm_gem_freedreno.c:
> diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h 
> b/drivers/gpu/drm/panfrost/panfrost_issues.h
> index 8e59d765bf19f..4e7cf979ee67a 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_issues.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
> @@ -13,8 +13,10 @@
>   * to care about.
>   */
>  enum panfrost_hw_issue {
> - /* Need way to guarantee that all previously-translated memory accesses
> -  * are commited */
> + /*
> +  * Need way to guarantee that all previously-translated memory accesses
> +  * are committed
> +  */

This file has a whole load of multiline comments that don't technically
follow the coding style. Fixing just one comment makes the file
inconsistent. Note we recently had a discussion about this[1] and
decided to leave the comment style as is. And I have to admit in this
instance avoiding the extra mostly-blank lines makes the list easier to
read. The typo fix is obviously welcomed though!

[1] https://lore.kernel.org/r/c7331489-ad04-0f35-224e-164f144fb819%40arm.com

>   HW_ISSUE_6367,
>  
>   /* On job complete with non-done the cache is not flushed */
> diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
> b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> index 39562f2d11a47..d3f82b26a631d 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> @@ -1,4 +1,4 @@
> -// SPDX-License-Identifier:  GPL-2.0
> +// SPDX-License-Identifier: GPL-2.0
>  /* Copyright 2019 Linaro, Ltd, Rob Herring  */
>  
>  #include 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h 
> b/drivers/gpu/drm/panfrost/panfrost_regs.h
> index 6c5a11ef1ee87..efe4b75149d35 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_regs.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
> @@ -292,7 +292,7 @@
>  #define AS_FAULTADDRESS_LO(as)   (MMU_AS(as) + 0x20) /* (RO) 
> Fault Address for address space n, low word */
>  #define AS_FAULTADDRESS_HI(as)   (MMU_AS(as) + 0x24) /* (RO) 
> Fault Address for address space n, high word */
>  #define AS_STATUS(as)(MMU_AS(as) + 0x28) /* (RO) 
> Status flags for address space n */
> -/* Additional Bifrost AS regsiters */
> +/* Additional Bifrost AS registers */
>  #define AS_TRANSCFG_LO(as)   (MMU_AS(as) + 0x30) /* (RW) Translation 
> table configuration for address space n, low word */
>  #define AS_TRANSCFG_HI(as)   (MMU_AS(as) + 0x34) /* (RW) Translation 
> table configuration for address space n, high word */
>  #define AS_FAULTEXTRA_LO(as) (MMU_AS(as) + 0x38) /* (RO) Secondary 
> fault address for address space n, low word */



Re: linux-next: build failure after merge of the kspp tree

2022-03-02 Thread Stephen Rothwell
Hi Kees,

On Mon, 28 Feb 2022 15:02:48 -0800 Kees Cook  wrote:
>
> On Tue, Mar 01, 2022 at 09:27:30AM +1100, Stephen Rothwell wrote:
> > 
> > After merging the kspp tree, today's linux-next build (x86_64
> > allmodconfig) failed like this:
> > 
> > drivers/gpu/drm/drm_dp_helper.c: In function 'drm_dp_pcon_dsc_bpp_incr':
> > drivers/gpu/drm/drm_dp_helper.c:3130:28: error: array subscript 12 is 
> > outside array bounds of 'const u8[12]' {aka 'const unsigned char[12]'} 
> > [-Werror=array-bounds]
> >  3130 | buf = pcon_dsc_dpcd[DP_PCON_DSC_BPP_INCR - 
> > DP_PCON_DSC_ENCODER];
> >   |   
> > ~^~~~
> > drivers/gpu/drm/drm_dp_helper.c:3126:39: note: while referencing 
> > 'pcon_dsc_dpcd'
> >  3126 | int drm_dp_pcon_dsc_bpp_incr(const u8 
> > pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
> >   |  
> > ~^~~
> > drivers/gpu/drm/drm_dp_helper.c: In function 
> > 'drm_dp_get_adjust_request_post_cursor':
> > drivers/gpu/drm/drm_dp_helper.c:59:27: error: array subscript 10 is outside 
> > array bounds of 'const u8[6]' {aka 'const unsigned char[6]'} 
> > [-Werror=array-bounds]
> >59 | return link_status[r - DP_LANE0_1_STATUS];
> >   |~~~^~~
> > drivers/gpu/drm/drm_dp_helper.c:147:51: note: while referencing 
> > 'link_status'
> >   147 | u8 drm_dp_get_adjust_request_post_cursor(const u8 
> > link_status[DP_LINK_STATUS_SIZE],
> >   |  
> > ~^~~~
> > cc1: all warnings being treated as errors
> > 
> > I can't see what in the kspp tree suddenly brought this on, so I have
> > used the kspp tree from next-20220228 for today.
> > 
> > In case it matters: x86_64-linux-gnu-gcc (Debian 11.2.0-9) 11.2.0  
> 
> This is fixed in drm-misc:
> 
> https://cgit.freedesktop.org/drm/drm-misc/log/
> https://cgit.freedesktop.org/drm/drm-misc/commit/?id=d4da1f27396fb1dde079447a3612f4f512caed07
> https://cgit.freedesktop.org/drm/drm-misc/commit/?id=a2151490cc6c57b368d7974ffd447a8b36ade639
> 
> but I had to drop the fix from the for-next/kspp because the patched
> file got moved in drm-misc.

Well, I moved the kspp tree to the end of the -next merges today, so it
would be after all the drm changes.  Unfortunately, it still fails:

drivers/gpu/drm/dp/drm_dp.c: In function 'drm_dp_pcon_dsc_bpp_incr':
drivers/gpu/drm/dp/drm_dp.c:3214:28: error: array subscript 12 is outside array 
bounds of 'const u8[12]' {aka 'const unsigned char[12]'} [-Werror=array-bounds]
 3214 | buf = pcon_dsc_dpcd[DP_PCON_DSC_BPP_INCR - DP_PCON_DSC_ENCODER];
  |   ~^~~~
drivers/gpu/drm/dp/drm_dp.c:3210:39: note: while referencing 'pcon_dsc_dpcd'
 3210 | int drm_dp_pcon_dsc_bpp_incr(const u8 
pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
  |  
~^~~
drivers/gpu/drm/dp/drm_dp.c: In function 
'drm_dp_get_adjust_request_post_cursor':
drivers/gpu/drm/dp/drm_dp.c:60:27: error: array subscript 10 is outside array 
bounds of 'const u8[6]' {aka 'const unsigned char[6]'} [-Werror=array-bounds]
   60 | return link_status[r - DP_LANE0_1_STATUS];
  |~~~^~~
drivers/gpu/drm/dp/drm_dp.c:211:51: note: while referencing 'link_status'
  211 | u8 drm_dp_get_adjust_request_post_cursor(const u8 
link_status[DP_LINK_STATUS_SIZE],
  |  
~^~~~

Presumably the above fixes have not hit the drm trees in linux-next yet
:-(

So, I used the version of your tree from next-20220228 again.  This
does not get the above, but does produce the error reported in
https://lore.kernel.org/lkml/20220225164231.904173-1-broo...@kernel.org/
(I was wondering why that went away today) for which I have applied the
patch in
https://lore.kernel.org/all/20220228081421.1504213-1-hsi...@chromium.org/

-- 
Cheers,
Stephen Rothwell


pgpsAfV5n9DJp.pgp
Description: OpenPGP digital signature


Re: [Intel-gfx] [PATCH 1/3] drm/i915/guc: Limit scheduling properties to avoid overflow

2022-03-02 Thread Tvrtko Ursulin



On 01/03/2022 19:57, John Harrison wrote:

On 3/1/2022 02:50, Tvrtko Ursulin wrote:

On 28/02/2022 18:32, John Harrison wrote:

On 2/28/2022 08:11, Tvrtko Ursulin wrote:

On 25/02/2022 17:39, John Harrison wrote:

On 2/25/2022 09:06, Tvrtko Ursulin wrote:


On 24/02/2022 19:19, John Harrison wrote:

[snip]


./gt/uc/intel_guc_fwif.h: u32 execution_quantum;

./gt/uc/intel_guc_submission.c: desc->execution_quantum = 
engine->props.timeslice_duration_ms * 1000;


./gt/intel_engine_types.h: unsigned long timeslice_duration_ms;

timeslice_store/preempt_timeout_store:
err = kstrtoull(buf, 0, &duration);

So both kconfig and sysfs can already overflow GuC, not only 
because of tick conversion internally but because at backend 
level nothing was done for assigning 64-bit into 32-bit. Or 
I failed to find where it is handled.
That's why I'm adding this range check to make sure we don't 
allow overflows.


Yes and no, this fixes it, but the first bug was not only due 
GuC internal tick conversion. It was present ever since the 
u64 from i915 was shoved into u32 sent to GuC. So even if GuC 
used the value without additional multiplication, bug was be 
there. My point being when GuC backend was added timeout_ms 
values should have been limited/clamped to U32_MAX. The tick 
discovery is additional limit on top.
I'm not disagreeing. I'm just saying that the truncation wasn't 
noticed until I actually tried using very long timeouts to 
debug a particular problem. Now that it is noticed, we need 
some method of range checking and this simple clamp solves all 
the truncation problems.


Agreed in principle, just please mention in the commit message 
all aspects of the problem.


I think we can get away without a Fixes: tag since it requires 
user fiddling to break things in unexpected ways.


I would though put in a code a clamping which expresses both, 
something like min(u32, ..GUC LIMIT..). So the full story is 
documented forever. Or "if > u32 || > ..GUC LIMIT..) return 
-EINVAL". Just in case GuC limit one day changes but u32 stays. 
Perhaps internal ticks go away or anything and we are left with 
plain 1:1 millisecond relationship.
Can certainly add a comment along the lines of "GuC API only 
takes a 32bit field but that is further reduced to GUC_LIMIT due 
to internal calculations which would otherwise overflow".


But if the GuC limit is > u32 then, by definition, that means the 
GuC API has changed to take a u64 instead of a u32. So there will 
no u32 truncation any more. So I'm not seeing a need to 
explicitly test the integer size when the value check covers that.


Hmm I was thinking if the internal conversion in the GuC fw 
changes so that GUC_POLICY_MAX_PREEMPT_TIMEOUT_MS goes above u32, 
then to be extra safe by documenting in code there is the 
additional limit of the data structure field. Say the field was 
changed to take some unit larger than a millisecond. Then the 
check against the GuC MAX limit define would not be enough, unless 
that would account both for internal implementation and u32 in the 
protocol. Maybe that is overdefensive but I don't see that it 
harms. 50-50, but it's do it once and forget so I'd do it.

Huh?

How can the limit be greater than a u32 if the interface only takes 
a u32? By definition the limit would be clamped to u32 size.


If you mean that the GuC policy is in different units and those 
units might not overflow but ms units do, then actually that is 
already the case. The GuC works in us not ms. That's part of why 
the wrap around is so low, we have to multiply by 1000 before 
sending to GuC. However, that is actually irrelevant because the 
comparison is being done on the i915 side in i915's units. We have 
to scale the GuC limit to match what i915 is using. And the i915 
side is u64 so if the scaling to i915 numbers overflows a u32 then 
who cares because that comparison can be done at 64 bits wide.


If the units change then that is a backwards breaking API change 
that will require a manual driver code update. You can't just 
recompile with a new header and magically get an ms to us or ms to 
s conversion in your a = b assignment. The code will need to be 
changed to do the new unit conversion (note we already convert from 
ms to us, the GuC API is all expressed in us). And that code change 
will mean having to revisit any and all scaling, type conversions, 
etc. I.e. any pre-existing checks will not necessarily be valid and 
will need to be re-visted anyway. But as above, any scaling to GuC 
units has to be incorporated into the limit already because 
otherwise the limit would not fit in the GuC's own API.


Yes I get that, I was just worried that u32 field in the protocol 
and GUC_POLICY_MAX_EXEC_QUANTUM_MS defines are separate in the 
source code and then how to protect against forgetting to update 
both in sync.


Like if the protocol was changed to take nanoseconds, and firmware 
implementation changed to support the full range, but define 
left/forgotten at 

[v4 0/5] enhanced edid driver compatibility

2022-03-02 Thread Lee Shawn C
Support to parse multiple CEA extension blocks and HF-EEODB to
extend drm edid driver's capability.

v4: add one more patch to support HF-SCDB

Lee Shawn C (5):
  drm/edid: seek for available CEA block from specific EDID block index
  drm/edid: parse multiple CEA extension block
  drm/edid: read HF-EEODB ext block
  drm/edid: parse HF-EEODB CEA extension block
  drm/edid: check for HF-SCDB block

 drivers/gpu/drm/drm_connector.c |   8 +-
 drivers/gpu/drm/drm_displayid.c |   5 +-
 drivers/gpu/drm/drm_edid.c  | 194 +---
 include/drm/drm_edid.h  |   4 +-
 4 files changed, 164 insertions(+), 47 deletions(-)

-- 
2.17.1



[v4 1/5] drm/edid: seek for available CEA block from specific EDID block index

2022-03-02 Thread Lee Shawn C
drm_find_cea_extension() always look for a top level CEA block. Pass
ext_index from caller then this function to search next available
CEA ext block from a specific EDID block pointer.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 42 ++
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a504542238ed..375e70d9de86 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3353,16 +3353,14 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid)
+static const u8 *drm_find_cea_extension(const struct edid *edid, int 
*ext_index)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
-   int ext_index = 0;
 
-   /* Look for a top level CEA extension block */
-   /* FIXME: make callers iterate through multiple CEA ext blocks? */
-   cea = drm_find_edid_extension(edid, CEA_EXT, &ext_index);
+   /* Look for a CEA extension block from ext_index */
+   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
if (cea)
return cea;
 
@@ -3643,10 +3641,10 @@ add_alternate_cea_modes(struct drm_connector 
*connector, struct edid *edid)
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *tmp;
LIST_HEAD(list);
-   int modes = 0;
+   int modes = 0, ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid))
+   if (!drm_find_cea_extension(edid, &ext_index))
return 0;
 
/*
@@ -4321,11 +4319,11 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea = drm_find_cea_extension(edid);
-   const u8 *db, *hdmi = NULL, *video = NULL;
+   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
u8 dbl, hdmi_len, video_len = 0;
-   int modes = 0;
+   int modes = 0, ext_index = 0;
 
+   cea = drm_find_cea_extension(edid, &ext_index);
if (cea && cea_revision(cea) >= 3) {
int i, start, end;
 
@@ -4562,7 +4560,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
uint8_t *eld = connector->eld;
const u8 *cea;
const u8 *db;
-   int total_sad_count = 0;
+   int total_sad_count = 0, ext_index = 0;
int mnl;
int dbl;
 
@@ -4571,7 +4569,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, &ext_index);
if (!cea) {
DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
return;
@@ -4655,11 +4653,11 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
  */
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
 {
-   int count = 0;
+   int count = 0, ext_index = 0;
int i, start, end, dbl;
const u8 *cea;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, &ext_index);
if (!cea) {
DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
return 0;
@@ -4717,11 +4715,11 @@ EXPORT_SYMBOL(drm_edid_to_sad);
  */
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
 {
-   int count = 0;
+   int count = 0, ext_index = 0;
int i, start, end, dbl;
const u8 *cea;
 
-   cea = drm_find_cea_extension(edid);
+   cea = drm_find_cea_extension(edid, &ext_index);
if (!cea) {
DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
return 0;
@@ -4814,9 +4812,9 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
 {
const u8 *edid_ext;
int i;
-   int start_offset, end_offset;
+   int start_offset, end_offset, ext_index = 0;
 
-   edid_ext = drm_find_cea_extension(edid);
+   edid_ext = drm_find_cea_extension(edid, &ext_index);
if (!edid_ext)
return false;
 
@@ -4853,9 +4851,9 @@ bool drm_detect_monitor_audio(struct edid *edid)
const u8 *edid_ext;
int i, j;
bool has_audio = false;
-   int start_offset, end_offset;
+   int start_offset, end_offset, ext_index = 0;
 
-   edid_ext = drm_find_cea_extension(edid);
+   edid_ext = drm_find_cea_extension(edid, &ext_index);
if (!edid_ext)
goto end;
 
@@ -5177,9 +5175,9 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
 {
struct drm_display_info *info = &connector->display_info;
const u8 *edid_ext;
-  

[v4 2/5] drm/edid: parse multiple CEA extension block

2022-03-02 Thread Lee Shawn C
Try to find and parse more CEA ext blocks if edid->extensions
is greater than one.

v2: split prvious patch to two. And do CEA block parsing
in this one.
v3: simplify this patch based on previous change.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 36 ++--
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 375e70d9de86..c4a47465ba76 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4319,16 +4319,24 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-   const u8 *cea, *db, *hdmi = NULL, *video = NULL;
-   u8 dbl, hdmi_len, video_len = 0;
+   const u8 *cea, *db;
+   u8 dbl, hdmi_len;
int modes = 0, ext_index = 0;
+   int i, start, end;
 
-   cea = drm_find_cea_extension(edid, &ext_index);
-   if (cea && cea_revision(cea) >= 3) {
-   int i, start, end;
+   for (;;) {
+   const u8 *hdmi = NULL, *video = NULL;
+   u8 video_len = 0;
+
+   cea = drm_find_cea_extension(edid, &ext_index);
+   if (!cea)
+   break;
+
+   if (cea_revision(cea) < 3)
+   continue;
 
if (cea_db_offsets(cea, &start, &end))
-   return 0;
+   continue;
 
for_each_cea_db(cea, i, start, end) {
db = &cea[i];
@@ -4350,15 +4358,15 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
  dbl - 1);
}
}
-   }
 
-   /*
-* We parse the HDMI VSDB after having added the cea modes as we will
-* be patching their flags when the sink supports stereo 3D.
-*/
-   if (hdmi)
-   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
-   video_len);
+   /*
+* We parse the HDMI VSDB after having added the cea modes as 
we will
+* be patching their flags when the sink supports stereo 3D.
+*/
+   if (hdmi)
+   modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, 
video,
+   video_len);
+   }
 
return modes;
 }
-- 
2.17.1



[v4 5/5] drm/edid: check for HF-SCDB block

2022-03-02 Thread Lee Shawn C
Find HF-SCDB information in CEA extensions block. And retrieve
Max_TMDS_Character_Rate that support by sink device.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_edid.c | 36 
 1 file changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 2b8ddc956ce2..d6b48c543c23 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3350,6 +3350,7 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
 #define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
 #define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
+#define EXT_VIDEO_HF_SCDB_DATA_BLOCK   0x79
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
@@ -4277,6 +4278,20 @@ static bool cea_db_is_vcdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hf_scdb(const u8 *db)
+{
+   if (cea_db_tag(db) != USE_EXTENDED_TAG)
+   return false;
+
+   if (cea_db_payload_len(db) < 7)
+   return false;
+
+   if (cea_db_extended_tag(db) != EXT_VIDEO_HF_SCDB_DATA_BLOCK)
+   return false;
+
+   return true;
+}
+
 static bool cea_db_is_y420cmdb(const u8 *db)
 {
if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -4987,6 +5002,25 @@ static void drm_parse_vcdb(struct drm_connector 
*connector, const u8 *db)
info->rgb_quant_range_selectable = true;
 }
 
+static void drm_parse_hf_scdb(struct drm_connector *connector, const u8 *db)
+{
+   struct drm_display_info *info = &connector->display_info;
+   u32 max_tmds_clock;
+
+   DRM_DEBUG_KMS("HF-SCDB version 0x%02x\n", db[4]);
+
+   max_tmds_clock = db[5] * 5000;
+   if (info->max_tmds_clock < max_tmds_clock) {
+   info->max_tmds_clock = max_tmds_clock;
+   DRM_DEBUG_KMS("HF-SCDB: max TMDS clock %d kHz\n",
+ info->max_tmds_clock);
+   }
+
+   /*
+* ToDo: Parse the remaining SCDB data if needed
+*/
+}
+
 static
 void drm_get_max_frl_rate(int max_frl_rate, u8 *max_lanes, u8 
*max_rate_per_lane)
 {
@@ -5282,6 +5316,8 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
drm_parse_y420cmdb_bitmap(connector, db);
if (cea_db_is_vcdb(db))
drm_parse_vcdb(connector, db);
+   if (cea_db_is_hf_scdb(db))
+   drm_parse_hf_scdb(connector, db);
if (cea_db_is_hdmi_hdr_metadata_block(db))
drm_parse_hdr_metadata_block(connector, db);
}
-- 
2.17.1



[v4 4/5] drm/edid: parse HF-EEODB CEA extension block

2022-03-02 Thread Lee Shawn C
While adding CEA modes, try to get available EEODB block
number. Then based on it to parse numbers of ext blocks,
retrieve CEA information and add more CEA modes.

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_displayid.c |  5 -
 drivers/gpu/drm/drm_edid.c  | 35 +++--
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 32da557b960f..dc649a9efaa2 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -37,7 +37,10 @@ static const u8 *drm_find_displayid_extension(const struct 
edid *edid,
  int *length, int *idx,
  int *ext_index)
 {
-   const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, 
ext_index);
+   const u8 *displayid = drm_find_edid_extension(edid,
+ DISPLAYID_EXT,
+ ext_index,
+ edid->extensions);
const struct displayid_header *base;
int ret;
 
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index e5ac9ab0b9d0..2b8ddc956ce2 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3360,23 +3360,23 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
  * Search EDID for CEA extension block.
  */
 const u8 *drm_find_edid_extension(const struct edid *edid,
- int ext_id, int *ext_index)
+ int ext_id, int *ext_index, int ext_blk_num)
 {
const u8 *edid_ext = NULL;
int i;
 
/* No EDID or EDID extensions */
-   if (edid == NULL || edid->extensions == 0)
+   if (edid == NULL || edid->extensions == 0 || *ext_index >= ext_blk_num)
return NULL;
 
/* Find CEA extension */
-   for (i = *ext_index; i < edid->extensions; i++) {
+   for (i = *ext_index; i < ext_blk_num; i++) {
edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
if (edid_ext[0] == ext_id)
break;
}
 
-   if (i >= edid->extensions)
+   if (i >= ext_blk_num)
return NULL;
 
*ext_index = i + 1;
@@ -3384,14 +3384,15 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid, int 
*ext_index)
+static const u8 *drm_find_cea_extension(const struct edid *edid,
+   int *ext_index, int ext_blk_num)
 {
const struct displayid_block *block;
struct displayid_iter iter;
const u8 *cea;
 
/* Look for a CEA extension block from ext_index */
-   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index);
+   cea = drm_find_edid_extension(edid, CEA_EXT, ext_index, ext_blk_num);
if (cea)
return cea;
 
@@ -3675,7 +3676,7 @@ add_alternate_cea_modes(struct drm_connector *connector, 
struct edid *edid)
int modes = 0, ext_index = 0;
 
/* Don't add CEA modes if the CEA extension block is missing */
-   if (!drm_find_cea_extension(edid, &ext_index))
+   if (!drm_find_cea_extension(edid, &ext_index, edid->extensions))
return 0;
 
/*
@@ -4327,7 +4328,7 @@ size_t drm_edid_read_hf_eeodb_blk_count(const struct edid 
*edid)
int i, start, end, ext_index = 0;
 
if (edid->extensions) {
-   cea = drm_find_cea_extension(edid, &ext_index);
+   cea = drm_find_cea_extension(edid, &ext_index, 
edid->extensions);
 
if (cea && !cea_db_offsets(cea, &start, &end))
for_each_cea_db(cea, i, start, end)
@@ -4386,12 +4387,16 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
u8 dbl, hdmi_len;
int modes = 0, ext_index = 0;
int i, start, end;
+   int ext_blk_num = drm_edid_read_hf_eeodb_blk_count(edid);
+
+   if (!ext_blk_num)
+   ext_blk_num = edid->extensions;
 
for (;;) {
const u8 *hdmi = NULL, *video = NULL;
u8 video_len = 0;
 
-   cea = drm_find_cea_extension(edid, &ext_index);
+   cea = drm_find_cea_extension(edid, &ext_index, ext_blk_num);
if (!cea)
break;
 
@@ -4640,7 +4645,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
if (!edid)
return;
 
-   cea = drm_find_cea_extension(edid, &ext_index);
+   cea = drm_find_cea_extension(edid, &ext_index, edid->extensions);
if (!cea) {
DRM_DEBUG_KMS("ELD: no CEA Extension foun

[v4 3/5] drm/edid: read HF-EEODB ext block

2022-03-02 Thread Lee Shawn C
According to HDMI 2.1 spec.

"The HDMI Forum EDID Extension Override Data Block (HF-EEODB)
is utilized by Sink Devices to provide an alternate method to
indicate an EDID Extension Block count larger than 1, while
avoiding the need to present a VESA Block Map in the first
E-EDID Extension Block."

It is a mandatory for HDMI 2.1 protocol compliance as well.
This patch help to know how many HF_EEODB blocks report by sink
and read allo HF_EEODB blocks back.

v2: support to find CEA block, check EEODB block format, and return
available block number in drm_edid_read_hf_eeodb_blk_count().

Cc: Jani Nikula 
Cc: Ville Syrjala 
Cc: Ankit Nautiyal 
Signed-off-by: Lee Shawn C 
---
 drivers/gpu/drm/drm_connector.c |  8 +++-
 drivers/gpu/drm/drm_edid.c  | 71 +++--
 include/drm/drm_edid.h  |  2 +-
 3 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index a50c82bc2b2f..16011023c12e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid)
 {
struct drm_device *dev = connector->dev;
-   size_t size = 0;
+   size_t size = 0, hf_eeodb_blk_count;
int ret;
const struct edid *old_edid;
 
@@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
if (connector->override_edid)
return 0;
 
-   if (edid)
+   if (edid) {
size = EDID_LENGTH * (1 + edid->extensions);
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
+   if (hf_eeodb_blk_count)
+   size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
+   }
 
/* Set the display info, using edid if available, otherwise
 * resetting the values to defaults. This duplicates the work
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index c4a47465ba76..e5ac9ab0b9d0 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
 {
int i, j = 0, valid_extensions = 0;
u8 *edid, *new;
+   size_t hf_eeodb_blk_count;
struct edid *override;
 
override = drm_get_override_edid(connector);
@@ -2051,7 +2052,35 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
}
 
kfree(edid);
+   return (struct edid *)new;
+   }
+
+   hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid 
*)edid);
+   if (hf_eeodb_blk_count >= 2) {
+   new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, 
GFP_KERNEL);
+   if (!new)
+   goto out;
edid = new;
+
+   valid_extensions = hf_eeodb_blk_count - 1;
+   for (j = 2; j <= hf_eeodb_blk_count; j++) {
+   u8 *block = edid + j * EDID_LENGTH;
+
+   for (i = 0; i < 4; i++) {
+   if (get_edid_block(data, block, j, EDID_LENGTH))
+   goto out;
+   if (drm_edid_block_valid(block, j, false, NULL))
+   break;
+   }
+
+   if (i == 4)
+   valid_extensions--;
+   }
+
+   if (valid_extensions != hf_eeodb_blk_count - 1) {
+   DRM_ERROR("Not able to retrieve proper EDID contain 
HF-EEODB data.\n");
+   goto out;
+   }
}
 
return (struct edid *)edid;
@@ -3315,15 +3344,17 @@ add_detailed_modes(struct drm_connector *connector, 
struct edid *edid,
 #define VIDEO_BLOCK 0x02
 #define VENDOR_BLOCK0x03
 #define SPEAKER_BLOCK  0x04
-#define HDR_STATIC_METADATA_BLOCK  0x6
-#define USE_EXTENDED_TAG 0x07
-#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define HDR_STATIC_METADATA_BLOCK  0x06
+#define USE_EXTENDED_TAG   0x07
 #define EXT_VIDEO_DATA_BLOCK_420   0x0E
-#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB   0x0F
+#define EXT_VIDEO_HF_EEODB_DATA_BLOCK  0x78
 #define EDID_BASIC_AUDIO   (1 << 6)
 #define EDID_CEA_YCRCB444  (1 << 5)
 #define EDID_CEA_YCRCB422  (1 << 4)
 #define EDID_CEA_VCDB_QS   (1 << 6)
+#define HF_EEODB_LENGTH2
 
 /*
  * Search EDID for CEA extension block.
@@ -4273,9 +4304,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
return true;
 }
 
+static bool cea_db_is_hdmi_forum_eeodb(const u8 *db)
+{
+   if (cea_db_tag(db) != USE_EXTENDED_TAG)
+   return false;
+
+   if (cea_db_payload_len(db) != HF_EEOD

Re: [PATCH 1/9] dt-bindings: mxsfb: Add compatible for i.MX8MP

2022-03-02 Thread Lucas Stach
Am Mittwoch, dem 02.03.2022 um 03:54 +0100 schrieb Marek Vasut:
> On 3/1/22 14:18, Lucas Stach wrote:
> > Am Dienstag, dem 01.03.2022 um 07:03 -0600 schrieb Adam Ford:
> > > On Tue, Mar 1, 2022 at 5:05 AM Lucas Stach  wrote:
> > > > 
> > > > Am Dienstag, dem 01.03.2022 um 11:19 +0100 schrieb Marek Vasut:
> > > > > On 3/1/22 11:04, Lucas Stach wrote:
> > > > > 
> > > > > Hi,
> > > > > 
> > > > > [...]
> > > > > 
> > > > > > > Given the two totally different IPs, I don't see bugs of IP 
> > > > > > > control
> > > > > > > logics should be fixed for both drivers. Naturally, the two would
> > > > > > > diverge due to different HWs. Looking at Patch 9/9, it basically
> > > > > > > squashes code to control LCDIFv3 into the mxsfb drm driver with
> > > > > > > 'if/else' checks(barely no common control code), which is hard to
> > > > > > > maintain and not able to achieve good scalability for both 
> > > > > > > 'LCDIFv3'
> > > > > > > and 'LCDIF'.
> > > > > > 
> > > > > > I tend to agree with Liu here. Writing a DRM driver isn't that much
> > > > > > boilerplate anymore with all the helpers we have available in the
> > > > > > framework today.
> > > > > 
> > > > > I did write a separate driver for this IP before I spent time merging
> > > > > them into single driver, that's when I realized a single driver is 
> > > > > much
> > > > > better and discarded the separate driver idea.
> > > > > 
> > > > > > The IP is so different from the currently supported LCDIF 
> > > > > > controllers
> > > > > > that I think trying to support this one in the existing driver 
> > > > > > actually
> > > > > > increases the chances to break something when modifying the driver 
> > > > > > in
> > > > > > the future. Not everyone is able to test all LCDIF versions. My 
> > > > > > vote is
> > > > > > on having a separate driver for the i.MX8MP LCDIF.
> > > > > 
> > > > > If you look at both controllers, it is clear it is still the LCDIF
> > > > > behind, even the CSC that is bolted on would suggest that.
> > > > 
> > > > Yes, but from a driver PoV what you care about is not really the
> > > > hardware blocks used to implement something, but the programming model,
> > > > i.e. the register interface exposed to software.
> > > > 
> > > > > 
> > > > > I am also not happy when I look at the amount of duplication a 
> > > > > separate
> > > > > driver would create, it will be some 50% of the code that would be 
> > > > > just
> > > > > duplicated.
> > > > > 
> > > > Yea, the duplicated code is still significant, as the HW itself is so
> > > > simple. However, if you find yourself in the situation where basically
> > > > every actual register access in the driver ends up being in a "if (some
> > > > HW rev) ... " clause, i still think it would be better to have a
> > > > separate driver, as the programming interface is just different.
> > > 
> > > I tend to agree with Marek on this one.  We have an instance where the
> > > blk-ctrl and the GPC driver between 8m, mini, nano, plus are close,
> > > but different enough where each SoC has it's own set of tables and
> > > some checks.   Lucas created the framework, and others adapted it for
> > > various SoC's.  If there really is nearly 50% common code for the
> > > LCDIF, why not either leave the driver as one or split the common code
> > > into its own driver like lcdif-common and then have smaller drivers
> > > that handle their specific variations.
> > 
> > I don't know exactly how the standalone driver looks like, but I guess
> > the overlap is not really in any real HW specific parts, but the common
> > DRM boilerplate, so there isn't much point in creating a common lcdif
> > driver.
> 
> The mxsfb currently has 1280 LoC as of patch 8/9 of this series. Of 
> that, there is some 400 LoC which are specific to old LCDIF and this 
> patch adds 380 LoC for the new LCDIF. So that's 800 LoC or ~60% of 
> shared boilerplate that would be duplicated .

That is probably ignoring the fact that the 8MP LCDIF does not support
any overlays, so it could use the drm_simple_display_pipe
infrastructure to reduce the needed boilerplate.
> 
> > As you brought up the blk-ctrl as an example: I'm all for supporting
> > slightly different hardware in the same driver, as long as the HW
> > interface is close enough. But then I also opted for a separate 8MP
> > blk-ctrl driver for those blk-ctrls that differ significantly from the
> > others, as I think it would make the common driver unmaintainable
> > trying to support all the different variants in one driver.
> 
> But then you also need to maintain two sets of boilerplate, they 
> diverge, and that is not good.

I don't think that there is much chance for bugs going unfixed due to
divergence in the boilerplate, especially if you use the simple pipe
framework to handle most of that stuff for you, which gives you a lot
of code sharing with other simple DRM drivers.

Regards,
Lucas




Re: [PATCH 2/6] treewide: remove using list iterator after loop body as a ptr

2022-03-02 Thread Rasmus Villemoes
On 02/03/2022 00.55, Linus Torvalds wrote:
> On Tue, Mar 1, 2022 at 3:19 PM David Laight  wrote:
>>

> With the "don't use iterator outside the loop" approach, the exact
> same code works in both the old world order and the new world order,
> and you don't have the semantic confusion. And *if* you try to use the
> iterator outside the loop, you'll _mostly_ (*) get a compiler warning
> about it not being initialized.
> 
>  Linus
> 
> (*) Unless somebody initializes the iterator pointer pointlessly.
> Which clearly does happen. Thus the "mostly". It's not perfect, and
> that's most definitely not nice - but it should at least hopefully
> make it that much harder to mess up.

This won't help the current issue (because it doesn't exist and might
never), but just in case some compiler people are listening, I'd like to
have some sort of way to tell the compiler "treat this variable as
uninitialized from here on". So one could do

#define kfree(p) do { __kfree(p); __magic_uninit(p); } while (0)

with __magic_uninit being a magic no-op that doesn't affect the
semantics of the code, but could be used by the compiler's "[is/may be]
used uninitialized" machinery to flag e.g. double frees on some odd
error path etc. It would probably only work for local automatic
variables, but it should be possible to just ignore the hint if p is
some expression like foo->bar or has side effects. If we had that, the
end-of-loop test could include that to "uninitialize" the iterator.

Maybe sparse/smatch or some other static analyzer could implement such a
magic thing? Maybe it's better as a function attribute
[__attribute__((uninitializes(1)))] to avoid having to macrofy all
functions that release resources.

Rasmus


Re: [PATCH 1/9] dt-bindings: mxsfb: Add compatible for i.MX8MP

2022-03-02 Thread Liu Ying
On Wed, 2022-03-02 at 10:23 +0100, Lucas Stach wrote:
> Am Mittwoch, dem 02.03.2022 um 03:54 +0100 schrieb Marek Vasut:
> > On 3/1/22 14:18, Lucas Stach wrote:
> > > Am Dienstag, dem 01.03.2022 um 07:03 -0600 schrieb Adam Ford:
> > > > On Tue, Mar 1, 2022 at 5:05 AM Lucas Stach  
> > > > wrote:
> > > > > Am Dienstag, dem 01.03.2022 um 11:19 +0100 schrieb Marek Vasut:
> > > > > > On 3/1/22 11:04, Lucas Stach wrote:
> > > > > > 
> > > > > > Hi,
> > > > > > 
> > > > > > [...]
> > > > > > 
> > > > > > > > Given the two totally different IPs, I don't see bugs of IP 
> > > > > > > > control
> > > > > > > > logics should be fixed for both drivers. Naturally, the two 
> > > > > > > > would
> > > > > > > > diverge due to different HWs. Looking at Patch 9/9, it basically
> > > > > > > > squashes code to control LCDIFv3 into the mxsfb drm driver with
> > > > > > > > 'if/else' checks(barely no common control code), which is hard 
> > > > > > > > to
> > > > > > > > maintain and not able to achieve good scalability for both 
> > > > > > > > 'LCDIFv3'
> > > > > > > > and 'LCDIF'.
> > > > > > > 
> > > > > > > I tend to agree with Liu here. Writing a DRM driver isn't that 
> > > > > > > much
> > > > > > > boilerplate anymore with all the helpers we have available in the
> > > > > > > framework today.
> > > > > > 
> > > > > > I did write a separate driver for this IP before I spent time 
> > > > > > merging
> > > > > > them into single driver, that's when I realized a single driver is 
> > > > > > much
> > > > > > better and discarded the separate driver idea.
> > > > > > 
> > > > > > > The IP is so different from the currently supported LCDIF 
> > > > > > > controllers
> > > > > > > that I think trying to support this one in the existing driver 
> > > > > > > actually
> > > > > > > increases the chances to break something when modifying the 
> > > > > > > driver in
> > > > > > > the future. Not everyone is able to test all LCDIF versions. My 
> > > > > > > vote is
> > > > > > > on having a separate driver for the i.MX8MP LCDIF.
> > > > > > 
> > > > > > If you look at both controllers, it is clear it is still the LCDIF
> > > > > > behind, even the CSC that is bolted on would suggest that.
> > > > > 
> > > > > Yes, but from a driver PoV what you care about is not really the
> > > > > hardware blocks used to implement something, but the programming 
> > > > > model,
> > > > > i.e. the register interface exposed to software.
> > > > > 
> > > > > > I am also not happy when I look at the amount of duplication a 
> > > > > > separate
> > > > > > driver would create, it will be some 50% of the code that would be 
> > > > > > just
> > > > > > duplicated.
> > > > > > 
> > > > > Yea, the duplicated code is still significant, as the HW itself is so
> > > > > simple. However, if you find yourself in the situation where basically
> > > > > every actual register access in the driver ends up being in a "if 
> > > > > (some
> > > > > HW rev) ... " clause, i still think it would be better to have a
> > > > > separate driver, as the programming interface is just different.
> > > > 
> > > > I tend to agree with Marek on this one.  We have an instance where the
> > > > blk-ctrl and the GPC driver between 8m, mini, nano, plus are close,
> > > > but different enough where each SoC has it's own set of tables and
> > > > some checks.   Lucas created the framework, and others adapted it for
> > > > various SoC's.  If there really is nearly 50% common code for the
> > > > LCDIF, why not either leave the driver as one or split the common code
> > > > into its own driver like lcdif-common and then have smaller drivers
> > > > that handle their specific variations.
> > > 
> > > I don't know exactly how the standalone driver looks like, but I guess
> > > the overlap is not really in any real HW specific parts, but the common
> > > DRM boilerplate, so there isn't much point in creating a common lcdif
> > > driver.
> > 
> > The mxsfb currently has 1280 LoC as of patch 8/9 of this series. Of 
> > that, there is some 400 LoC which are specific to old LCDIF and this 
> > patch adds 380 LoC for the new LCDIF. So that's 800 LoC or ~60% of 
> > shared boilerplate that would be duplicated .
> 
> That is probably ignoring the fact that the 8MP LCDIF does not support
> any overlays, so it could use the drm_simple_display_pipe
> infrastructure to reduce the needed boilerplate.

The drm_simple_display_pipe infrastructure is probably too simple for
i.MX8MP LCDIF, since it uses one only crtc for one drm device. i.MX8MP
embeds *three* LCDIF instances to support MIPI DSI, LVDS and HDMI
outputs respectively. To use that infrastructure means there would be
three dri cards in all. However, the three LCDIF instances can be
wrapped by the one drm device, which is not the boilerplate code in the
current mxsfb driver may handle.

Regards,
Liu Ying

> > > As you brought up the blk-ctrl as an example: I'm all for supporting
> > > slightly different hardware in the same driver, a

[PATCH] drm/xlnx: Handle error for dma_set_mask

2022-03-02 Thread Jiasheng Jiang
As the potential failure of the dma_set_mask(),
it should be better to check it and return error
if fails.

Fixes: d76271d22694 ("drm: xlnx: DRM/KMS driver for Xilinx ZynqMP DisplayPort 
Subsystem")
Signed-off-by: Jiasheng Jiang 
---
 drivers/gpu/drm/xlnx/zynqmp_dpsub.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c 
b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
index ac37053412a1..5bb42d0a2de9 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
@@ -200,7 +200,9 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev)
dpsub->dev = &pdev->dev;
platform_set_drvdata(pdev, dpsub);
 
-   dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT));
+   ret = dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT));
+   if (ret)
+   return ret;
 
/* Try the reserved memory. Proceed if there's none. */
of_reserved_mem_device_init(&pdev->dev);
-- 
2.25.1



Re: [Intel-gfx] [PATCH v2 1/3] drm/i915/guc: Limit scheduling properties to avoid overflow

2022-03-02 Thread Tvrtko Ursulin



On 25/02/2022 20:41, john.c.harri...@intel.com wrote:

From: John Harrison 

GuC converts the pre-emption timeout and timeslice quantum values into
clock ticks internally. That significantly reduces the point of 32bit
overflow. On current platforms, worst case scenario is approximately
110 seconds. Rather than allowing the user to set higher values and
then get confused by early timeouts, add limits when setting these
values.

v2: Add helper functins for clamping (review feedback from Tvrtko).

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio  (v1)
---
  drivers/gpu/drm/i915/gt/intel_engine.h  |  6 ++
  drivers/gpu/drm/i915/gt/intel_engine_cs.c   | 69 +
  drivers/gpu/drm/i915/gt/sysfs_engines.c | 25 +---
  drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h |  9 +++
  4 files changed, 99 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h 
b/drivers/gpu/drm/i915/gt/intel_engine.h
index be4b1e65442f..5a9186f784c4 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -349,4 +349,10 @@ intel_engine_get_hung_context(struct intel_engine_cs 
*engine)
return engine->hung_ce;
  }
  
+u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value);

+u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 
value);
+u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value);
+u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value);
+u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 
value);
+
  #endif /* _INTEL_RINGBUFFER_H_ */
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index e855c801ba28..7ad9e6006656 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -399,6 +399,26 @@ static int intel_engine_setup(struct intel_gt *gt, enum 
intel_engine_id id,
if (GRAPHICS_VER(i915) == 12 && engine->class == RENDER_CLASS)
engine->props.preempt_timeout_ms = 0;
  
+	/* Cap properties according to any system limits */

+#define CLAMP_PROP(field) \
+   do { \
+   u64 clamp = intel_clamp_##field(engine, engine->props.field); \
+   if (clamp != engine->props.field) { \
+   drm_notice(&engine->i915->drm, \
+  "Warning, clamping %s to %lld to prevent 
overflow\n", \
+  #field, clamp); \
+   engine->props.field = clamp; \
+   } \
+   } while (0)
+
+   CLAMP_PROP(heartbeat_interval_ms);
+   CLAMP_PROP(max_busywait_duration_ns);
+   CLAMP_PROP(preempt_timeout_ms);
+   CLAMP_PROP(stop_timeout_ms);
+   CLAMP_PROP(timeslice_duration_ms);
+
+#undef CLAMP_PROP
+
engine->defaults = engine->props; /* never to change again */
  
  	engine->context_size = intel_engine_context_size(gt, engine->class);

@@ -421,6 +441,55 @@ static int intel_engine_setup(struct intel_gt *gt, enum 
intel_engine_id id,
return 0;
  }
  
+u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value)

+{
+   value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
+
+   return value;
+}
+
+u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 
value)
+{
+   value = min(value, jiffies_to_nsecs(2));
+
+   return value;
+}
+
+u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value)
+{
+   /*
+* NB: The GuC API only supports 32bit values. However, the limit is 
further
+* reduced due to internal calculations which would otherwise overflow.
+*/
+   if (intel_guc_submission_is_wanted(&engine->gt->uc.guc))
+   value = min_t(u64, value, GUC_POLICY_MAX_PREEMPT_TIMEOUT_MS);
+
+   value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
+
+   return value;
+}
+
+u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value)
+{
+   value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
+
+   return value;
+}
+
+u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 
value)
+{
+   /*
+* NB: The GuC API only supports 32bit values. However, the limit is 
further
+* reduced due to internal calculations which would otherwise overflow.
+*/
+   if (intel_guc_submission_is_wanted(&engine->gt->uc.guc))
+   value = min_t(u64, value, GUC_POLICY_MAX_EXEC_QUANTUM_MS);
+
+   value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
+
+   return value;
+}
+
  static void __setup_engine_capabilities(struct intel_engine_cs *engine)
  {
struct drm_i915_private *i915 = engine->i915;
diff --git a/drivers/gpu/drm/i915/gt/sysfs_engines.c 
b/drivers/gpu/drm/i915/gt/sysfs_engines.c
index 967031056202..f2d

Re: [PATCH V2 01/12] drm: bridge: icn6211: Fix register layout

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:19AM +0100, Marek Vasut wrote:
> The chip register layout has nothing to do with MIPI DCS, the registers
> incorrectly marked as MIPI DCS in the driver are regular chip registers
> often with completely different function.
> 
> Fill in the actual register names and bits from [1] and [2] and add the
> entire register layout, since the documentation for this chip is hard to
> come by.
> 
> [1] 
> https://github.com/rockchip-linux/kernel/blob/develop-4.19/drivers/gpu/drm/bridge/icn6211.c
> [2] https://github.com/tdjastrzebski/ICN6211-Configurator
> 
> Fixes: ce517f18944e3 ("drm: bridge: Add Chipone ICN6211 MIPI-DSI to RGB 
> bridge")
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org

I don't know this device, so I'll trust you on that one
Acked-by: Maxime Ripard 

Maxime


signature.asc
Description: PGP signature


Re: [PATCH V2 02/12] drm: bridge: icn6211: Fix HFP_HSW_HBP_HI and HFP_MIN handling

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:20AM +0100, Marek Vasut wrote:
> The HFP_HSW_HBP_HI register must be programmed with 2 LSbits of each
> Horizontal Front Porch/Sync/Back Porch. Currently the driver programs
> this register to 0, which breaks displays with either value above 255.
> 
> The HFP_MIN register must be set to the same value as HFP_LI, otherwise
> there is visible image distortion, usually in the form of missing lines
> at the bottom of the panel.
> 
> Fix this by correctly programming the HFP_HSW_HBP_HI and HFP_MIN registers.
> 
> Fixes: ce517f18944e3 ("drm: bridge: Add Chipone ICN6211 MIPI-DSI to RGB 
> bridge")
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org

Acked-by: Maxime Ripard 

Maxime


signature.asc
Description: PGP signature


Re: [PATCH V2 03/12] drm: bridge: icn6211: Add HS/VS/DE polarity handling

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:21AM +0100, Marek Vasut wrote:
> The driver currently hard-codes HS/VS polarity to active-low and DE to
> active-high, which is not correct for a lot of supported DPI panels.
> Add the missing mode flag handling for HS/VS/DE polarity.
> 
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org
> ---
> V2: Rebase on next-20220214
> ---
>  drivers/gpu/drm/bridge/chipone-icn6211.c | 16 +++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c 
> b/drivers/gpu/drm/bridge/chipone-icn6211.c
> index e29e6a84c39a6..2ac8eb7e25f52 100644
> --- a/drivers/gpu/drm/bridge/chipone-icn6211.c
> +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c
> @@ -165,8 +165,16 @@ static void chipone_atomic_enable(struct drm_bridge 
> *bridge,
> struct drm_bridge_state *old_bridge_state)
>  {
>   struct chipone *icn = bridge_to_chipone(bridge);
> + struct drm_atomic_state *state = old_bridge_state->base.state;
>   struct drm_display_mode *mode = &icn->mode;
> + const struct drm_bridge_state *bridge_state;
>   u16 hfp, hbp, hsync;
> + u32 bus_flags;
> + u8 pol;
> +
> + /* Get the DPI flags from the bridge state. */
> + bridge_state = drm_atomic_get_new_bridge_state(state, bridge);
> + bus_flags = bridge_state->output_bus_cfg.flags;
>  
>   ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_DSI);
>  
> @@ -206,7 +214,13 @@ static void chipone_atomic_enable(struct drm_bridge 
> *bridge,
>   ICN6211_DSI(icn, HFP_MIN, hfp & 0xff);
>   ICN6211_DSI(icn, MIPI_PD_CK_LANE, 0xa0);
>   ICN6211_DSI(icn, PLL_CTRL(12), 0xff);
> - ICN6211_DSI(icn, BIST_POL, BIST_POL_DE_POL);
> +
> + /* DPI HS/VS/DE polarity */
> + pol = ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? BIST_POL_HSYNC_POL : 0) |
> +   ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? BIST_POL_VSYNC_POL : 0) |
> +   ((bus_flags & DRM_BUS_FLAG_DE_HIGH) ? BIST_POL_DE_POL : 0);

Is there a reason you didn't use bus_flags for all the polarities there?

Maxime


signature.asc
Description: PGP signature


Re: [PATCH V2 04/12] drm: bridge: icn6211: Add DSI lane count DT property parsing

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:22AM +0100, Marek Vasut wrote:
> The driver currently hard-codes DSI lane count to two, however the chip
> is capable of operating in 1..4 DSI lanes mode. Parse 'data-lanes' DT
> property and program the result into DSI_CTRL register.
> 
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org
> ---
> V2: Rebase on next-20220214
> ---
>  drivers/gpu/drm/bridge/chipone-icn6211.c | 21 -
>  1 file changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c 
> b/drivers/gpu/drm/bridge/chipone-icn6211.c
> index 2ac8eb7e25f52..7c013a08c7b00 100644
> --- a/drivers/gpu/drm/bridge/chipone-icn6211.c
> +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c
> @@ -136,10 +136,12 @@ struct chipone {
>   struct drm_bridge bridge;
>   struct drm_display_mode mode;
>   struct drm_bridge *panel_bridge;
> + struct device_node *host_node;
>   struct gpio_desc *enable_gpio;
>   struct regulator *vdd1;
>   struct regulator *vdd2;
>   struct regulator *vdd3;
> + int dsi_lanes;
>  };
>  
>  static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge)
> @@ -212,6 +214,11 @@ static void chipone_atomic_enable(struct drm_bridge 
> *bridge,
>   /* dsi specific sequence */
>   ICN6211_DSI(icn, SYNC_EVENT_DLY, 0x80);
>   ICN6211_DSI(icn, HFP_MIN, hfp & 0xff);
> +
> + /* DSI data lane count */
> + ICN6211_DSI(icn, DSI_CTRL,
> + DSI_CTRL_UNKNOWN | DSI_CTRL_DSI_LANES(icn->dsi_lanes - 1));
> +
>   ICN6211_DSI(icn, MIPI_PD_CK_LANE, 0xa0);
>   ICN6211_DSI(icn, PLL_CTRL(12), 0xff);
>  
> @@ -314,6 +321,7 @@ static const struct drm_bridge_funcs chipone_bridge_funcs 
> = {
>  static int chipone_parse_dt(struct chipone *icn)
>  {
>   struct device *dev = icn->dev;
> + struct device_node *endpoint;
>   struct drm_panel *panel;
>   int ret;
>  
> @@ -350,6 +358,16 @@ static int chipone_parse_dt(struct chipone *icn)
>   return PTR_ERR(icn->enable_gpio);
>   }
>  
> + endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
> + icn->dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes");

The binding must be amended to allow for the usage of data-lanes, and
you need to keep the previous value as default for older device trees

Maxime


signature.asc
Description: PGP signature


Re: [PATCH V2 05/12] drm: bridge: icn6211: Add generic DSI-to-DPI PLL configuration

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:23AM +0100, Marek Vasut wrote:
> The chip contains fractional PLL, however the driver currently hard-codes
> one specific PLL setting. Implement generic PLL parameter calculation code,
> so any DPI panel with arbitrary pixel clock can be attached to this bridge.
> 
> The datasheet for this bridge is not available, the PLL behavior has been
> inferred from [1] and [2] and by analyzing the DPI pixel clock with scope.
> The PLL limits might be wrong, but at least the calculated values match all
> the example code available. This is better than one hard-coded pixel clock
> value anyway.
> 
> [1] 
> https://github.com/rockchip-linux/kernel/blob/develop-4.19/drivers/gpu/drm/bridge/icn6211.c
> [2] https://github.com/tdjastrzebski/ICN6211-Configurator
> 
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org

Acked-by: Maxime Ripard 

Maxime


signature.asc
Description: PGP signature


Re: [PATCH V2 06/12] drm: bridge: icn6211: Use DSI burst mode without EoT and with LP command mode

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:24AM +0100, Marek Vasut wrote:
> The DSI burst mode is more energy efficient than the DSI sync pulse mode,
> make use of the burst mode since the chip supports it as well. Disable the
> generation of EoT packet, the chip ignores it, so no point in emitting it.
> Enable transmission of data in LP mode, otherwise register read via DSI
> does not work with this chip.
> 
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org

Acked-by: Maxime Ripard 

Maxime


signature.asc
Description: PGP signature


Re: [PATCH V2 07/12] drm: bridge: icn6211: Disable DPI color swap

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:25AM +0100, Marek Vasut wrote:
> The chip is capable of swapping DPI RGB channels. The driver currently
> does not implement support for this functionality. Write the MIPI_PN_SWAP
> register to 0 to assure the color swap is disabled.
> 
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org

Acked-by: Maxime Ripard 

Maxime


signature.asc
Description: PGP signature


Re: [PATCH V2 08/12] drm: bridge: icn6211: Set SYS_CTRL_1 to value used in examples

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:26AM +0100, Marek Vasut wrote:
> Both example code [1], [2] as well as one provided by custom panel vendor
> set register SYS_CTRL_1 to 0x88. What exactly does the value mean is unknown
> due to unavailable datasheet. Align this register value with example code.
> 
> [1] 
> https://github.com/rockchip-linux/kernel/blob/develop-4.19/drivers/gpu/drm/bridge/icn6211.c
> [2] https://github.com/tdjastrzebski/ICN6211-Configurator
> 
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org

Acked-by: Maxime Ripard 

Maxime


signature.asc
Description: PGP signature


Re: [PATCH V2 09/12] drm: bridge: icn6211: Implement atomic_get_input_bus_fmts

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:27AM +0100, Marek Vasut wrote:
> Implement .atomic_get_input_bus_fmts callback, which sets up the
> input (DSI-end) format, and that format can then be used in pipeline
> format negotiation between the DSI-end of this bridge and the other
> component closer to the scanout engine.
> 
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org

Acked-by: Maxime Ripard 

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v12 19/23] drm/mediatek: add dma dev get function

2022-03-02 Thread AngeloGioacchino Del Regno

Il 22/02/22 11:07, Nancy.Lin ha scritto:

This is a preparation for adding support for the ovl_adaptor sub driver
Ovl_adaptor is a DRM sub driver, which doesn't have dma dev. Add
dma_dev_get function for getting representative dma dev in ovl_adaptor.

Signed-off-by: Nancy.Lin 


Reviewed-by: AngeloGioachino Del Regno 


Re: [PATCH V2 10/12] drm: bridge: icn6211: Add I2C configuration support

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:28AM +0100, Marek Vasut wrote:
> The ICN6211 chip starts in I2C configuration mode after cold boot.
> Implement support for configuring the chip via I2C in addition to
> the current DSI LP command mode configuration support. The later
> seems to be available only on chips which have additional MCU on
> the panel/bridge board which preconfigures the ICN6211, while the
> I2C configuration mode added by this patch does not require any
> such MCU.
> 
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org

Acked-by: Maxime Ripard 

Maxime


signature.asc
Description: PGP signature


Re: [PATCH V2 11/12] drm: bridge: icn6211: Rework ICN6211_DSI to chipone_writeb()

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:29AM +0100, Marek Vasut wrote:
> Rename and inline macro ICN6211_DSI() into function chipone_writeb()
> to keep all function names lower-case. No functional change.
> 
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org

Acked-by: Maxime Ripard 

Maxime


signature.asc
Description: PGP signature


Re: [PATCH V2 12/12] drm: bridge: icn6211: Read and validate chip IDs before configuration

2022-03-02 Thread Maxime Ripard
On Thu, Feb 17, 2022 at 01:25:30AM +0100, Marek Vasut wrote:
> Read out the Vendor/Chip/Version ID registers from the chip before
> performing any configuration, and validate that the registers have
> correct values. This is mostly a simple test whether DSI register
> access does work, since that tends to be broken on various bridges.
> 
> Signed-off-by: Marek Vasut 
> Cc: Jagan Teki 
> Cc: Maxime Ripard 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> To: dri-devel@lists.freedesktop.org

Acked-by: Maxime Ripard 

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v12 23/23] arm64: dts: mt8195: add display node for vdosys1

2022-03-02 Thread AngeloGioacchino Del Regno

Il 22/02/22 11:07, Nancy.Lin ha scritto:

Add display node for vdosys1.

Signed-off-by: Nancy.Lin 
---
  arch/arm64/boot/dts/mediatek/mt8195.dtsi | 222 +++
  1 file changed, 222 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index e136761345db..a69a7b57e070 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -10,6 +10,7 @@
  #include 
  #include 
  #include 
+#include 
  
  / {

compatible = "mediatek,mt8195";
@@ -20,6 +21,22 @@
aliases {
gce0 = &gce0;
gce1 = &gce1;
+   ethdr0 = ðdr0;
+   mutex0 = &mutex;
+   mutex1 = &mutex1;
+   merge1 = &merge1;
+   merge2 = &merge2;
+   merge3 = &merge3;
+   merge4 = &merge4;
+   merge5 = &merge5;
+   vdo1_rdma0 = &vdo1_rdma0;


If you really need these aliases, then they should not have underscores.

vdo1-rdma0 = &vdo1_rdma0;


+   vdo1_rdma1 = &vdo1_rdma1;
+   vdo1_rdma2 = &vdo1_rdma2;
+   vdo1_rdma3 = &vdo1_rdma3;
+   vdo1_rdma4 = &vdo1_rdma4;
+   vdo1_rdma5 = &vdo1_rdma5;
+   vdo1_rdma6 = &vdo1_rdma6;
+   vdo1_rdma7 = &vdo1_rdma7;
};
  
  	clocks {

@@ -1235,7 +1252,212 @@
vdosys1: syscon@1c10 {
compatible = "mediatek,mt8195-vdosys1", "syscon";
reg = <0 0x1c10 0 0x1000>;
+   mboxes = <&gce0 1 CMDQ_THR_PRIO_4>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x 
0x1000>;
#clock-cells = <1>;
+   #reset-cells = <1>;
+   };
+
+   mutex1: disp_mutex0@1c101000 {


Please, no underscores.

This should be either mutex@1c101000 or disp-mutex@1c101000.
I prefer the first one, without "disp-" prefix.


+   compatible = "mediatek,mt8195-disp-mutex";
+   reg = <0 0x1c101000 0 0x1000>;
+   reg-names = "vdo1_mutex";
+   interrupts = ;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   clocks = <&vdosys1 CLK_VDO1_DISP_MUTEX>;
+   clock-names = "vdo1_mutex";
+   mediatek,gce-events = 
;
+   };
+
+   vdo1_rdma0: vdo1_rdma@1c104000 {


vdo1_rdma0: disp-rdma@1c104000 or, simply, vdo1_rdma0: rdma@1c104000

... Same for the others.


+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c104000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x4000 
0x1000>;
+   };
+
+   vdo1_rdma1: vdo1_rdma@1c105000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c105000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA1>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA1>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x5000 
0x1000>;
+   };
+
+   vdo1_rdma2: vdo1_rdma@1c106000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c106000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA2>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA2>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x6000 
0x1000>;
+   };
+
+   vdo1_rdma3: vdo1_rdma@1c107000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c107000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA3>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA3>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x7000 
0x1000>;
+   };
+
+   vdo1_rdma4: vdo1_rdma@1c108000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c108000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA4>;
+   

Re: [PATCH v12 01/23] dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195

2022-03-02 Thread AngeloGioacchino Del Regno

Il 22/02/22 11:07, Nancy.Lin ha scritto:

Add vdosys1 RDMA definition.

Signed-off-by: Nancy.Lin 
---
  .../arm/mediatek/mediatek,mdp-rdma.yaml   | 77 +++
  1 file changed, 77 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml

diff --git 
a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml 
b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml
new file mode 100644
index ..d70b81ec1914
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/mediatek/mediatek,mdp-rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MDP RDMA
+
+maintainers:
+  - Matthias Brugger 
+
+description: |
+  The mediatek MDP RDMA stands for Read Direct Memory Access.
+  It provides real time data to the back-end panel driver, such as DSI,
+  DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for 
details.
+
+properties:
+  compatible:
+oneOf:
+  - items:
+  - const: mediatek,mt8195-vdo1-rdma
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  power-domains:
+description: A phandle and PM domain specifier as defined by bindings of
+  the power controller specified by phandle. See
+  Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+items:
+  - description: RDMA Clock
+
+  iommus:
+description:
+  This property should point to the respective IOMMU block with master 
port as argument,
+  see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for 
details.
+
+  mediatek,gce-client-reg:
+description:
+  The register of display function block to be set by gce. There are 4 
arguments,
+  such as gce node, subsys id, offset and register size. The subsys id 
that is
+  mapping to the register of display function blocks is defined in the gce 
header
+  include/include/dt-bindings/gce/-gce.h of each chips.
+$ref: /schemas/types.yaml#/definitions/phandle-array
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |


You're missing a couple of header inclusions and relying on the default
address-cells, size-cells, which is wrong here, as you have two of both.

#include .

soc {
#address-cells = <2>;
#size-cells = <2>;

vdo1_rdma0: ...


+
+vdo1_rdma0: vdo1_rdma@1c104000 {
+compatible = "mediatek,mt8195-vdo1-rdma";
+reg = <0 0x1c104000 0 0x1000>;
+interrupts = ;
+clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x4000 0x1000>;
+};
+


Re: [PATCH v12 03/23] dt-bindings: mediatek: add ethdr definition for mt8195

2022-03-02 Thread AngeloGioacchino Del Regno

Il 22/02/22 11:07, Nancy.Lin ha scritto:

Add vdosys1 ETHDR definition.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
---
  .../display/mediatek/mediatek,ethdr.yaml  | 147 ++
  1 file changed, 147 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
new file mode 100644
index ..131eed5eeeb7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ethdr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Ethdr Device Tree Bindings
+
+maintainers:
+  - Chun-Kuang Hu 
+  - Philipp Zabel 
+
+description: |
+  ETHDR is designed for HDR video and graphics conversion in the external 
display path.
+  It handles multiple HDR input types and performs tone mapping, color 
space/color
+  format conversion, and then combine different layers, output the required 
HDR or
+  SDR signal to the subsequent display path. This engine is composed of two 
video
+  frontends, two graphic frontends, one video backend and a mixer. ETHDR has 
two
+  DMA function blocks, DS and ADL. These two function blocks read the 
pre-programmed
+  registers from DRAM and set them to HW in the v-blanking period.
+
+properties:
+  compatible:
+items:
+  - const: mediatek,mt8195-disp-ethdr
+  reg:
+maxItems: 7
+  reg-names:
+items:
+  - const: mixer
+  - const: vdo_fe0
+  - const: vdo_fe1
+  - const: gfx_fe0
+  - const: gfx_fe1
+  - const: vdo_be
+  - const: adl_ds
+  interrupts:
+minItems: 1
+  iommus:
+description: The compatible property is DMA function blocks.
+  Should point to the respective IOMMU block with master port as argument,
+  see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for
+  details.
+minItems: 1
+maxItems: 2
+  clocks:
+items:
+  - description: mixer clock
+  - description: video frontend 0 clock
+  - description: video frontend 1 clock
+  - description: graphic frontend 0 clock
+  - description: graphic frontend 1 clock
+  - description: video backend clock
+  - description: autodownload and menuload clock
+  - description: video frontend 0 async clock
+  - description: video frontend 1 async clock
+  - description: graphic frontend 0 async clock
+  - description: graphic frontend 1 async clock
+  - description: video backend async clock
+  - description: ethdr top clock
+  clock-names:
+items:
+  - const: mixer
+  - const: vdo_fe0
+  - const: vdo_fe1
+  - const: gfx_fe0
+  - const: gfx_fe1
+  - const: vdo_be
+  - const: adl_ds
+  - const: vdo_fe0_async
+  - const: vdo_fe1_async
+  - const: gfx_fe0_async
+  - const: gfx_fe1_async
+  - const: vdo_be_async
+  - const: ethdr_top
+  power-domains:
+maxItems: 1
+  resets:
+maxItems: 5
+  mediatek,gce-client-reg:
+$ref: /schemas/types.yaml#/definitions/phandle-array
+description: The register of display function block to be set by gce.
+  There are 4 arguments in this property, gce node, subsys id, offset and
+  register size. The subsys id is defined in the gce header of each chips
+  include/include/dt-bindings/gce/-gce.h, mapping to the register of
+  display function block.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |


Please fix inclusions and address/size cells.

Thanks,
Angelo


+
+disp_ethdr@1c114000 {
+compatible = "mediatek,mt8195-disp-ethdr";
+reg = <0 0x1c114000 0 0x1000>,
+  <0 0x1c115000 0 0x1000>,
+  <0 0x1c117000 0 0x1000>,
+  <0 0x1c119000 0 0x1000>,
+  <0 0x1c11A000 0 0x1000>,
+  <0 0x1c11B000 0 0x1000>,
+  <0 0x1c11C000 0 0x1000>;
+reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+"vdo_be", "adl_ds";
+mediatek,gce-client-reg = <&gce0 SUBSYS_1c11 0x4000 0x1000>,
+  <&gce0 SUBSYS_1c11 0x5000 0x1000>,
+  <&gce0 SUBSYS_1c11 0x7000 0x1000>,
+  <&gce0 SUBSYS_1c11 0x9000 0x1000>,
+  <&gce0 SUBSYS_1c11 0xA000 0x1000>,
+  <&gce0 SUBSYS_1c11 0xB000 0x1000>,
+  <&gce0 SUBSYS_1c11 0xC000 0x1000>;
+clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
+

Re: [PATCH v12 04/23] dt-bindings: reset: mt8195: add vdosys1 reset control bit

2022-03-02 Thread AngeloGioacchino Del Regno

Il 22/02/22 11:07, Nancy.Lin ha scritto:

Add vdosys1 reset control bit for MT8195 platform.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 




Reviewed-by: AngeloGioacchino Del Regno 



[PATCH v2 0/3] vm- and vma cleanups

2022-03-02 Thread Thomas Hellström
The first patch of the series addresses a vm open count bug by
removing the vm open count.

The second patch removes the vma refcount that is no longer needed;
the vma is kept a live by taking the vm refcount and object lock.

Finally the last patch removes some unnecessary code. There should be
no functional changes.

Thomas Hellström (3):
  drm/i915: Remove the vm open count
  drm/i915: Remove the vma refcount
  drm/i915/gem: Remove some unnecessary code

 drivers/gpu/drm/i915/display/intel_dpt.c  |  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_context.c   | 29 ++-
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|  6 ++
 .../gpu/drm/i915/gem/selftests/mock_context.c |  5 +-
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c  |  2 +-
 drivers/gpu/drm/i915/gt/intel_ggtt.c  | 30 +++
 drivers/gpu/drm/i915/gt/intel_gtt.c   | 54 
 drivers/gpu/drm/i915/gt/intel_gtt.h   | 56 
 drivers/gpu/drm/i915/gt/selftest_execlists.c  | 86 +--
 drivers/gpu/drm/i915/i915_gem.c   | 55 ++--
 drivers/gpu/drm/i915/i915_vma.c   | 69 +--
 drivers/gpu/drm/i915/i915_vma.h   | 14 ---
 drivers/gpu/drm/i915/i915_vma_resource.c  |  2 +-
 drivers/gpu/drm/i915/i915_vma_resource.h  |  6 ++
 drivers/gpu/drm/i915/i915_vma_types.h |  8 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  4 +-
 16 files changed, 216 insertions(+), 212 deletions(-)

-- 
2.34.1



[PATCH v2 1/3] drm/i915: Remove the vm open count

2022-03-02 Thread Thomas Hellström
vms are not getting properly closed. Rather than fixing that,
Remove the vm open count and instead rely on the vm refcount.

The vm open count existed solely to break the strong references the
vmas had on the vms. Now instead make those references weak and
ensure vmas are destroyed when the vm is destroyed.

Unfortunately if the vm destructor and the object destructor both
wants to destroy a vma, that may lead to a race in that the vm
destructor just unbinds the vma and leaves the actual vma destruction
to the object destructor. However in order for the object destructor
to ensure the vma is unbound it needs to grab the vm mutex. In order
to keep the vm mutex alive until the object destructor is done with
it, somewhat hackishly grab a vm_resv refcount that is released late
in the vma destruction process, when the vm mutex is no longer needed.

v2: Address review-comments from Niranjana
- Clarify that the struct i915_address_space::skip_pte_rewrite is a hack and
  should ideally be replaced in an upcoming patch.
- Remove an unneeded continue in clear_vm_list and update comment.

Co-developed-by: Niranjana Vishwanathapura 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/i915/display/intel_dpt.c  |  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_context.c   | 29 ++-
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|  6 ++
 .../gpu/drm/i915/gem/selftests/mock_context.c |  5 +-
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c  |  2 +-
 drivers/gpu/drm/i915/gt/intel_ggtt.c  | 30 +++
 drivers/gpu/drm/i915/gt/intel_gtt.c   | 54 
 drivers/gpu/drm/i915/gt/intel_gtt.h   | 56 
 drivers/gpu/drm/i915/gt/selftest_execlists.c  | 86 +--
 drivers/gpu/drm/i915/i915_gem.c   |  6 +-
 drivers/gpu/drm/i915/i915_vma.c   | 55 
 drivers/gpu/drm/i915/i915_vma_resource.c  |  2 +-
 drivers/gpu/drm/i915/i915_vma_resource.h  |  6 ++
 drivers/gpu/drm/i915/i915_vma_types.h |  7 ++
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  4 +-
 15 files changed, 186 insertions(+), 164 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c 
b/drivers/gpu/drm/i915/display/intel_dpt.c
index 05dd7dba3a5c..3af4930c1095 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt.c
@@ -300,5 +300,5 @@ void intel_dpt_destroy(struct i915_address_space *vm)
 {
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
 
-   i915_vm_close(&dpt->vm);
+   i915_vm_put(&dpt->vm);
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index bc6d59df064d..fe872e02b395 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -1456,8 +1456,6 @@ static void set_closed_name(struct i915_gem_context *ctx)
 
 static void context_close(struct i915_gem_context *ctx)
 {
-   struct i915_address_space *vm;
-
/* Flush any concurrent set_engines() */
mutex_lock(&ctx->engines_mutex);
unpin_engines(__context_engines_static(ctx));
@@ -1469,19 +1467,6 @@ static void context_close(struct i915_gem_context *ctx)
 
set_closed_name(ctx);
 
-   vm = ctx->vm;
-   if (vm) {
-   /* i915_vm_close drops the final reference, which is a bit too
-* early and could result in surprises with concurrent
-* operations racing with thist ctx close. Keep a full reference
-* until the end.
-*/
-   i915_vm_get(vm);
-   i915_vm_close(vm);
-   }
-
-   ctx->file_priv = ERR_PTR(-EBADF);
-
/*
 * The LUT uses the VMA as a backpointer to unref the object,
 * so we need to clear the LUT before we close all the VMA (inside
@@ -1489,6 +1474,8 @@ static void context_close(struct i915_gem_context *ctx)
 */
lut_close(ctx);
 
+   ctx->file_priv = ERR_PTR(-EBADF);
+
spin_lock(&ctx->i915->gem.contexts.lock);
list_del(&ctx->link);
spin_unlock(&ctx->i915->gem.contexts.lock);
@@ -1587,12 +1574,8 @@ i915_gem_create_context(struct drm_i915_private *i915,
}
vm = &ppgtt->vm;
}
-   if (vm) {
-   ctx->vm = i915_vm_open(vm);
-
-   /* i915_vm_open() takes a reference */
-   i915_vm_put(vm);
-   }
+   if (vm)
+   ctx->vm = vm;
 
mutex_init(&ctx->engines_mutex);
if (pc->num_user_engines >= 0) {
@@ -1642,7 +1625,7 @@ i915_gem_create_context(struct drm_i915_private *i915,
free_engines(e);
 err_vm:
if (ctx->vm)
-   i915_vm_close(ctx->vm);
+   i915_vm_put(ctx->vm);
 err_ctx:
kfree(ctx);
return ERR_PTR(err);
@@ -1826,7 +1809,7 @@ static int get_ppgtt(struct drm_i915_file_private 
*file_priv,
if (err)
return err;
 
-

[PATCH v2 2/3] drm/i915: Remove the vma refcount

2022-03-02 Thread Thomas Hellström
Now that i915_vma_parked() is taking the object lock on vma destruction,
and the only user of the vma refcount, i915_gem_object_unbind()
also takes the object lock, remove the vma refcount.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/i915/i915_gem.c   | 17 +
 drivers/gpu/drm/i915/i915_vma.c   | 14 +++---
 drivers/gpu/drm/i915/i915_vma.h   | 14 --
 drivers/gpu/drm/i915/i915_vma_types.h |  1 -
 4 files changed, 16 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index dd84ebabb50f..c26110abcc0b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -151,14 +151,25 @@ int i915_gem_object_unbind(struct drm_i915_gem_object 
*obj,
break;
}
 
+   /*
+* Requiring the vm destructor to take the object lock
+* before destroying a vma would help us eliminate the
+* i915_vm_tryget() here, AND thus also the barrier stuff
+* at the end. That's an easy fix, but sleeping locks in
+* a kthread should generally be avoided.
+*/
ret = -EAGAIN;
if (!i915_vm_tryget(vma->vm))
break;
 
-   /* Prevent vma being freed by i915_vma_parked as we unbind */
-   vma = __i915_vma_get(vma);
spin_unlock(&obj->vma.lock);
 
+   /*
+* Since i915_vma_parked() takes the object lock
+* before vma destruction, it won't race us here,
+* and destroy the vma from under us.
+*/
+
if (vma) {
bool vm_trylock = !!(flags & 
I915_GEM_OBJECT_UNBIND_VM_TRYLOCK);
ret = -EBUSY;
@@ -180,8 +191,6 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
ret = i915_vma_unbind(vma);
}
}
-
-   __i915_vma_put(vma);
}
 
i915_vm_put(vma->vm);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 91538bc38110..6fd25b39748f 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -122,7 +122,6 @@ vma_create(struct drm_i915_gem_object *obj,
if (vma == NULL)
return ERR_PTR(-ENOMEM);
 
-   kref_init(&vma->ref);
vma->ops = &vm->vma_ops;
vma->obj = obj;
vma->size = obj->base.size;
@@ -1628,15 +1627,6 @@ void i915_vma_reopen(struct i915_vma *vma)
__i915_vma_remove_closed(vma);
 }
 
-void i915_vma_release(struct kref *ref)
-{
-   struct i915_vma *vma = container_of(ref, typeof(*vma), ref);
-
-   i915_active_fini(&vma->active);
-   GEM_WARN_ON(vma->resource);
-   i915_vma_free(vma);
-}
-
 static void force_unbind(struct i915_vma *vma)
 {
if (!drm_mm_node_allocated(&vma->node))
@@ -1665,7 +1655,9 @@ static void release_references(struct i915_vma *vma, bool 
vm_ddestroy)
if (vm_ddestroy)
i915_vm_resv_put(vma->vm);
 
-   __i915_vma_put(vma);
+   i915_active_fini(&vma->active);
+   GEM_WARN_ON(vma->resource);
+   i915_vma_free(vma);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 67ae7341c7e0..6034991d89fe 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -222,20 +222,6 @@ void i915_vma_unlink_ctx(struct i915_vma *vma);
 void i915_vma_close(struct i915_vma *vma);
 void i915_vma_reopen(struct i915_vma *vma);
 
-static inline struct i915_vma *__i915_vma_get(struct i915_vma *vma)
-{
-   if (kref_get_unless_zero(&vma->ref))
-   return vma;
-
-   return NULL;
-}
-
-void i915_vma_release(struct kref *ref);
-static inline void __i915_vma_put(struct i915_vma *vma)
-{
-   kref_put(&vma->ref, i915_vma_release);
-}
-
 void i915_vma_destroy_locked(struct i915_vma *vma);
 void i915_vma_destroy(struct i915_vma *vma);
 
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h 
b/drivers/gpu/drm/i915/i915_vma_types.h
index eac36be184e5..be6e028c3b57 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -211,7 +211,6 @@ struct i915_vma {
 * handles (but same file) for execbuf, i.e. the number of aliases
 * that exist in the ctx->handle_vmas LUT for this vma.
 */
-   struct kref ref;
atomic_t open_count;
atomic_t flags;
/**
-- 
2.34.1



[PATCH v2 3/3] drm/i915/gem: Remove some unnecessary code

2022-03-02 Thread Thomas Hellström
The test for vma should always return true, and when assigning -EBUSY
to ret, the variable should already have that value.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/i915/i915_gem.c | 32 ++--
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c26110abcc0b..9747924cc57b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -118,6 +118,7 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
   unsigned long flags)
 {
struct intel_runtime_pm *rpm = &to_i915(obj->base.dev)->runtime_pm;
+   bool vm_trylock = !!(flags & I915_GEM_OBJECT_UNBIND_VM_TRYLOCK);
LIST_HEAD(still_in_list);
intel_wakeref_t wakeref;
struct i915_vma *vma;
@@ -170,26 +171,21 @@ int i915_gem_object_unbind(struct drm_i915_gem_object 
*obj,
 * and destroy the vma from under us.
 */
 
-   if (vma) {
-   bool vm_trylock = !!(flags & 
I915_GEM_OBJECT_UNBIND_VM_TRYLOCK);
-   ret = -EBUSY;
-   if (flags & I915_GEM_OBJECT_UNBIND_ASYNC) {
-   assert_object_held(vma->obj);
-   ret = i915_vma_unbind_async(vma, vm_trylock);
-   }
+   ret = -EBUSY;
+   if (flags & I915_GEM_OBJECT_UNBIND_ASYNC) {
+   assert_object_held(vma->obj);
+   ret = i915_vma_unbind_async(vma, vm_trylock);
+   }
 
-   if (ret == -EBUSY && (flags & 
I915_GEM_OBJECT_UNBIND_ACTIVE ||
- !i915_vma_is_active(vma))) {
-   if (vm_trylock) {
-   if (mutex_trylock(&vma->vm->mutex)) {
-   ret = __i915_vma_unbind(vma);
-   mutex_unlock(&vma->vm->mutex);
-   } else {
-   ret = -EBUSY;
-   }
-   } else {
-   ret = i915_vma_unbind(vma);
+   if (ret == -EBUSY && (flags & I915_GEM_OBJECT_UNBIND_ACTIVE ||
+ !i915_vma_is_active(vma))) {
+   if (vm_trylock) {
+   if (mutex_trylock(&vma->vm->mutex)) {
+   ret = __i915_vma_unbind(vma);
+   mutex_unlock(&vma->vm->mutex);
}
+   } else {
+   ret = i915_vma_unbind(vma);
}
}
 
-- 
2.34.1



Re: [PATCH v16 4/4] drm/bridge: dw-hdmi: fix bus formats negotiation for 8 bit modes

2022-03-02 Thread Neil Armstrong

H,

On 01/03/2022 21:37, H. Nikolaus Schaller wrote:

Hi Neil,



Am 01.03.2022 um 10:18 schrieb Neil Armstrong :

Hi,

On 26/02/2022 18:13, H. Nikolaus Schaller wrote:

Commit 7cd70656d1285b ("drm/bridge: display-connector: implement bus fmts 
callbacks")
introduced a new mechanism to negotiate bus formats between hdmi connectors
and bridges which is to be used e.g. for the jz4780 based CI20 board.
In this case dw-hdmi sets up a list of formats in
dw_hdmi_bridge_atomic_get_output_bus_fmts().
This includes e.g. MEDIA_BUS_FMT_UYVY8_1X16 which is chosen for the CI20 but
only produces a black screen.
Analysis revealed an omission in
Commit 6c3c719936dafe ("drm/bridge: synopsys: dw-hdmi: add bus format 
negociation")
to check for 8 bit with when adding UYVY8 or YUV8 formats.
This fix is based on the observation that max_bpc = 0 when running this
function while info->bpc = 8.


In fact if bpc = 0, it should be considered as 8, so the issue is elsewhere.


Adding the proposed patch makes the jz4780/CI20 panel work again with default
MEDIA_BUS_FMT_RGB888_1X24 mode.
Fixes: 7cd70656d1285b ("drm/bridge: display-connector: implement bus fmts 
callbacks")
Fixes: 6c3c719936dafe ("drm/bridge: synopsys: dw-hdmi: add bus format 
negociation")
Signed-off-by: H. Nikolaus Schaller 
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 43e375da131e8..c08e2cc96584c 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2621,11 +2621,13 @@ static u32 
*dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
}
  - if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422)
-   output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
+   if (max_bpc >= 8 && info->bpc >= 8) {
+   if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422)
+   output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
  - if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
-   output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
+   if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
+   output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
+   }


It should not select YUV here if it's not possible, so something is wrong.

Can you check if 
https://lore.kernel.org/r/20220119123656.1456355-2-narmstr...@baylibre.com 
fixes this issue instead ?


Well, I had to manually fix it to be appliable to drm-misc/drm-misc-next
and specifically:

c03d0b52ff71 ("drm/connector: Fix typo in output format")

My resulting patch is attached.

Unfortunately it did not work.

I added a printk for hdmi->sink_is_hdmi. This returns 1. Which IMHO is to be 
expected
since I am using a HDMI connector and panel... So your patch will still add the 
UYVY formats.

Either the synposys module inside the jz4780 or the panel does not understand 
them.


By selecting the UYVY formats, the driver will enable the colorspace converters 
in the dw-hdmi IP,
I don't see why it doesn't work here...

There is a bit called `Support Color Space Converter` in config0_id:
bit |   Name|   R/W |   Desc
2   |   csc |   R   |   Indicates if Color Space 
Conversion block is present

Could you dump all the config0 bits:

===><=
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 54d8fdad395f..547731482da8 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -3431,6 +3431,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device 
*pdev,
pdevinfo.id = PLATFORM_DEVID_AUTO;

config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID);
+   dev_info(dev, "config0: %x\n", config0);
config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);

if (iores && config3 & HDMI_CONFIG3_AHBAUDDMA) {
===><=

If this bit is missing, this would explain the black screen.

Neil



Here is the EDID. Unfortunately it does not pretty print the extended 
descriptors for UYVY etc.
so that I don't know the exact capabilities of the panel. And what I am not 
sure is if the
jz4780 SoC can convert to UYVY or how it can.

root@letux:~# parse-edid 
sink_is_hdmi=1

So please let me know which parameters I should try to printk()...

BR and thanks,
Nikolaus


--

 From c84a3c4a500684e57b1243fe5386696c48fa1e1b Mon Sep 17 00:00:00 2001
From: Neil Armstrong 
Date: Wed, 19 Jan 2022 13:36:56 +0100
Subject: [PATCH] drm/bridge: dw-hdmi: filter out YUV output formats when DVI

When the display is not an HDMI sink, only the RGB output format is
valid. Thus stop returning YUV output formats when sink is not HDMI.

Fixes: 6c3c719936da ("drm/bridg

Re: linux-next: build warning after merge of the drm tree

2022-03-02 Thread Hans de Goede
Hi,

On 3/2/22 02:34, Stephen Rothwell wrote:
> Hi all,
> 
> On Wed, 2 Feb 2022 09:38:37 +0100 Hans de Goede  wrote:
>>
>> On 2/2/22 05:03, Stephen Rothwell wrote:
>>>
>>> On Wed, 2 Feb 2022 15:02:01 +1100 Stephen Rothwell  
>>> wrote:  

 After merging the drm tree, today's linux-next build (htmldocs) produced
 this warning:

 drivers/gpu/drm/drm_privacy_screen.c:X: warning: Function parameter or 
 member 'data' not described in 'drm_privacy_screen_register'  
>>>
>>> Actually:
>>>
>>> drivers/gpu/drm/drm_privacy_screen.c:392: warning: Function parameter or 
>>> member 'data' not described in 'drm_privacy_screen_register'  
>>
>> Thank you for reporting this, I will prepare a patch fixing this.
> 
> I am still seeing this warning.

Weird, this should be fixed by:

https://cgit.freedesktop.org/drm-misc/commit/?id=ccbeca4ca04302d129602093c8d611065e3f7958

Which was added to the "drm-misc-next-2022-02-23" drm-misc tag/pull-req 7 days 
ago,
which was merged into drm-next 6 days ago ?

I just reverted that did a make htmldocs and got the warning, then re-applied 
and
the warning was gone...

Regards,

Hans



Re: [PATCH] drm/i915/gt: Handle errors for i915_gem_object_trylock

2022-03-02 Thread Tvrtko Ursulin



+ Thomas, Matt

On 02/03/2022 06:19, Jiasheng Jiang wrote:

As the potential failure of the i915_gem_object_trylock(),
it should be better to check it and return error if fails.

Fixes: 94ce0d65076c ("drm/i915/gt: Setup a default migration context on the GT")
Signed-off-by: Jiasheng Jiang 
---
  drivers/gpu/drm/i915/gt/selftest_migrate.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_migrate.c 
b/drivers/gpu/drm/i915/gt/selftest_migrate.c
index fa4293d2944f..79c6c68f7316 100644
--- a/drivers/gpu/drm/i915/gt/selftest_migrate.c
+++ b/drivers/gpu/drm/i915/gt/selftest_migrate.c
@@ -465,7 +465,11 @@ create_init_lmem_internal(struct intel_gt *gt, size_t sz, 
bool try_lmem)
return obj;
}
  
-	i915_gem_object_trylock(obj, NULL);


Guys why is this a trylock to start with? (Since being added in 
94ce0d65076c ("drm/i915/gt: Setup a default migration context on the GT").


Surely it can't ever fail since the object has just been created.

Regards,

Tvrtko


+   if (!i915_gem_object_trylock(obj, NULL)) {
+   i915_gem_object_put(obj);
+   return ERR_PTR(-EBUSY);
+   }
+
err = i915_gem_object_pin_pages(obj);
if (err) {
i915_gem_object_unlock(obj);


Re: [PATCH v1 2/3] drm/panel: Add panel driver for NewVision NV3052C based LCDs

2022-03-02 Thread Paul Cercueil

Hi Christophe,

Le mar., mars 1 2022 at 16:31:21 +0100, Christophe Branchereau 
 a écrit :

This driver supports the NewVision NV3052C based LCDs. Right now, it
only supports the LeadTek LTK035C5444T 2.4" 640x480 TFT LCD panel, 
which

can be found in the Anbernic RG-350M handheld console.


You'd need to add a binding documentation for the NV3052C (in a 
separate patch).




Signed-off-by: Christophe Branchereau 
---
 drivers/gpu/drm/panel/Kconfig |   9 +
 drivers/gpu/drm/panel/Makefile|   1 +
 .../gpu/drm/panel/panel-newvision-nv3052c.c   | 504 
++

 3 files changed, 514 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-newvision-nv3052c.c

diff --git a/drivers/gpu/drm/panel/Kconfig 
b/drivers/gpu/drm/panel/Kconfig

index bb2e47229c68..40084f709789 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -283,6 +283,15 @@ config DRM_PANEL_NEC_NL8048HL11
 	  panel (found on the Zoom2/3/3630 SDP boards). To compile this 
driver

  as a module, choose M here.

+config DRM_PANEL_NEWVISION_NV3052C
+   tristate "NewVision NV3052C RGB/SPI panel"
+   depends on OF && SPI
+   depends on BACKLIGHT_CLASS_DEVICE
+   select DRM_MIPI_DBI
+   help
+ Say Y here if you want to enable support for the panels built
+ around the NewVision NV3052C display controller.
+
 config DRM_PANEL_NOVATEK_NT35510
tristate "Novatek NT35510 RGB panel driver"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile 
b/drivers/gpu/drm/panel/Makefile

index 5740911f637c..42a7ab54234b 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += 
panel-leadtek-ltk500hd1829.o

 obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
 obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
+obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += 
panel-newvision-nv3052c.o

 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35560) += panel-novatek-nt35560.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o
diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c 
b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c

new file mode 100644
index ..08a3b33bcce0
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c
@@ -0,0 +1,504 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NevVision NV3052C IPS LCD panel driver
+ *
+ * Copyright (C) 2020, Paul Cercueil 
+ * Copyright (C) 2022, Christophe Branchereau 


+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+struct nv3052c_panel_info {
+   const struct drm_display_mode *display_modes;
+   unsigned int num_modes;
+   u16 width_mm, height_mm;
+   u32 bus_format, bus_flags;
+};
+
+struct nv3052c {
+   struct device *dev;
+   struct drm_panel panel;
+   struct mipi_dbi dbi;
+
+   const struct nv3052c_panel_info *panel_info;
+
+   struct regulator *supply;
+   struct gpio_desc *reset_gpio;
+};
+
+struct nv3052c_reg {
+   u8 cmd;
+   u8 val;
+};
+
+static const struct nv3052c_reg nv3052c_panel_regs[] = {
+   { 0xff, 0x30 },
+   { 0xff, 0x52 },
+   { 0xff, 0x01 },
+   { 0xe3, 0x00 },
+   { 0x40, 0x00 },
+   { 0x03, 0x40 },
+   { 0x04, 0x00 },
+   { 0x05, 0x03 },
+   { 0x08, 0x00 },
+   { 0x09, 0x07 },
+   { 0x0a, 0x01 },
+   { 0x0b, 0x32 },
+   { 0x0c, 0x32 },
+   { 0x0d, 0x0b },
+   { 0x0e, 0x00 },
+   { 0x23, 0xa0 },
+
+   { 0x24, 0x0c },
+   { 0x25, 0x06 },
+   { 0x26, 0x14 },
+   { 0x27, 0x14 },
+
+   { 0x38, 0xcc },
+   { 0x39, 0xd7 },
+   { 0x3a, 0x4a },
+
+   { 0x28, 0x40 },
+   { 0x29, 0x01 },
+   { 0x2a, 0xdf },
+   { 0x49, 0x3c },
+   { 0x91, 0x77 },
+   { 0x92, 0x77 },
+   { 0xa0, 0x55 },
+   { 0xa1, 0x50 },
+   { 0xa4, 0x9c },
+   { 0xa7, 0x02 },
+   { 0xa8, 0x01 },
+   { 0xa9, 0x01 },
+   { 0xaa, 0xfc },
+   { 0xab, 0x28 },
+   { 0xac, 0x06 },
+   { 0xad, 0x06 },
+   { 0xae, 0x06 },
+   { 0xaf, 0x03 },
+   { 0xb0, 0x08 },
+   { 0xb1, 0x26 },
+   { 0xb2, 0x28 },
+   { 0xb3, 0x28 },
+   { 0xb4, 0x33 },
+   { 0xb5, 0x08 },
+   { 0xb6, 0x26 },
+   { 0xb7, 0x08 },
+   { 0xb8, 0x26 },
+   { 0xf0, 0x00 },
+   { 0xf6, 0xc0 },
+
+   { 0xff, 0x30 },
+   { 0xff, 0x52 },
+   { 0xff, 0x02 },
+   { 0xb0, 0x0b },
+   { 0xb1, 0x16 },
+   { 0xb2, 0x17 },
+   { 0xb3, 0x2c },
+   { 0xb4, 0x32 },
+   { 0xb5, 0x3b },
+   { 0xb6, 0x29 },
+   { 0xb7, 0x40 },
+   { 0xb8, 0x0d },
+   { 0xb9, 0x05 },
+   { 0xba, 0x12 },
+   { 0xbb, 0x10 },
+

Re: [Intel-gfx] [PATCH 2/3] drm/i915/gt: Make the heartbeat play nice with long pre-emption timeouts

2022-03-02 Thread Tvrtko Ursulin



On 01/03/2022 20:59, John Harrison wrote:

On 3/1/2022 04:09, Tvrtko Ursulin wrote:


I'll trim it a bit again..

On 28/02/2022 18:55, John Harrison wrote:

On 2/28/2022 09:12, Tvrtko Ursulin wrote:

On 25/02/2022 18:48, John Harrison wrote:

On 2/25/2022 10:14, Tvrtko Ursulin wrote:


[snip]

Your only objection is that ends up with too long total time 
before reset? Or something else as well?
An unnecessarily long total heartbeat timeout is the main 
objection. (2.5 + 12) * 5 = 72.5 seconds. That is a massive change 
from the current 12.5s.


If we are happy with that huge increase then fine. But I'm pretty 
sure you are going to get a lot more bug reports about hung systems 
not recovering. 10-20s is just about long enough for someone to 
wait before leaning on the power button of their machine. Over a 
minute is not. That kind of delay is going to cause support issues.


Sorry I wrote 12s, while you actually said tP * 12, so 7.68s, chosen 
just so it is longer than tH * 3?


And how do you keep coming up with factor of five? Isn't it four 
periods before "heartbeat stopped"? (Prio normal, hearbeat, barrier 
and then reset.)

Prio starts at low not normal.


Right, slipped my mind since I only keep seeing that one priority 
ladder block in intel_engine_heartbeat.c/heartbeat()..


From the point of view of user experience I agree reasonable 
responsiveness is needed before user "reaches for the power button".


In your proposal we are talking about 3 * 2.5s + 2 * 7.5s, so 22.5s.

Question of workloads.. what is the actual preempt timeout compute 
is happy with? And I don't mean compute setups with disabled 
hangcheck, which you say they want anyway, but if we target defaults 
for end users. Do we have some numbers on what they are likely to run?
Not that I have ever seen. This is all just finger in the air stuff. 
I don't recall if we invented the number and the compute people 
agreed with it or if they proposed the number to us.


Yeah me neither. And found nothing in my email archives. :(

Thinking about it today I don't see that disabled timeout is a 
practical default.


With it, if users have something un-preemptable to run (assuming prio 
normal), it would get killed after ~13s (5 * 2.5).


If we go for my scheme it gets killed in ~17.5s (3 * (2.5 + 2.5) + 2.5 
(third pulse triggers preempt timeout)).


And if we go for your scheme it gets killed in ~22.5s (4 * 2.5 + 2 * 3 
* 2.5).
Erm, that is not an apples to apples comparison. Your 17.5 is for an 
engine reset tripped by the pre-emption timeout, but your 22.5s is for a 
GT reset tripped by the heartbeat reaching the end and nuking the universe.


Right, in your scheme I did get it wrong. It would wait for GuC to reset 
the engine at the end, rather than hit the fake "hearbeat stopped" in 
that case, full reset path.


4 * 2.5 to trigger a max prio pulse, then 3 * 2.5 preempt timeout for 
GuC to reset (last hearbeat delay extended so it does not trigger). So 
17.5 as well.


If you are saying that the first pulse at sufficient priority (third 
being normal prio) is what causes the reset because the system is 
working as expected and the pre-emption timeout trips the reset. In that 
case, you have two periods to get to normal prio plus one pre-emption 
timeout to trip the reset. I.e. (tH * 2) + tP.


Your scheme is then tH(actual) = tH(user) + tP, yes?
So pre-emption based reset is after ((tH(user) + tP) * 2) + tP => (3 * 
tP) + (2 * tH)

And GT based reset is after (tH(user) + tP) * 5 => (5 * tP) + (5 * tH)

My scheme is tH(actual) = tH(user) for first four, then max(tH(user), 
tP) for fifth.

So pre-emption based reset is after tH(user) * 2 + tP = > tP + (2 * tH);
And GT based reset is after (tH(user) * 4) + (max(tH(user), tP) * 1) => 
greater of ((4 * tH) + tP) or (5 * tH)


Either way your scheme is longer. With tH(user) = 2.5s, tP(RCS) = 7.5s, 
we get 27.5s for engine and 50s for GT versus my 12.5s for engine and 
17.5s for GT. With tP(RCS) = 2.5s, yours is 12.5s for engine and 25s for 
GT versus my 7.5s for engine and 12.5s for GT.


Plus, not sure why your calculations above are using 2.5 for tP? Are you 
still arguing that 7.5s is too long? That is a separate issue and not 
related to the heartbeat algorithms. tP must be long enough to allow 
'out of box OpenCL workloads to complete'. That doesn't just mean not 
being killed by the heartbeat, it also means not being killed by running 
two of them concurrently (or one plus desktop OpenGL rendering) and not 
having it killed by basic time slicing between the two contexts. The 
heartbeat is not involved in that process. That is purely the 
pre-emption timeout. And that is the fundamental reason why tP needs to 
be much larger on RCS/CCS.


I was assuming 2.5s tP is enough and basing all calculation on that. 
Heartbeat or timeslicing regardless. I thought we established neither of 
us knows how long is enough.


Are you now saying 2.5s is definitely not enough? How is that usable for 
a def

Re: [PATCH v16 4/4] drm/bridge: dw-hdmi: fix bus formats negotiation for 8 bit modes

2022-03-02 Thread H. Nikolaus Schaller
Hi Neil,

> Am 02.03.2022 um 11:25 schrieb Neil Armstrong :
> 
>> I added a printk for hdmi->sink_is_hdmi. This returns 1. Which IMHO is to be 
>> expected
>> since I am using a HDMI connector and panel... So your patch will still add 
>> the UYVY formats.
>> Either the synposys module inside the jz4780 or the panel does not 
>> understand them.
> 
> By selecting the UYVY formats, the driver will enable the colorspace 
> converters in the dw-hdmi IP,
> I don't see why it doesn't work here...
> 
> There is a bit called `Support Color Space Converter` in config0_id:
> bit   |   Name|   R/W |   Desc
> 2 |   csc |   R   |   Indicates if Color Space 
> Conversion block is present
> 
> Could you dump all the config0 bits:
> 
> ===><=
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 54d8fdad395f..547731482da8 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -3431,6 +3431,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device 
> *pdev,
>pdevinfo.id = PLATFORM_DEVID_AUTO;
> 
>config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID);
> +   dev_info(dev, "config0: %x\n", config0);
>config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);
> 
>if (iores && config3 & HDMI_CONFIG3_AHBAUDDMA) {
> ===><=
> 
> If this bit is missing, this would explain the black screen.

[9.291011] dw-hdmi-ingenic 1018.hdmi: config0: bf

Hm. Or is the color-space conversion of the sw-hdmi module inside the jz4780 
broken
or not configured properly?

(cross-checked: RGB mode still works if I force hdmi->sink_is_hdmi = false)

BR and thanks,
Nikolaus



Re: [Intel-gfx] [PATCH 0/3] Improve anti-pre-emption w/a for compute workloads

2022-03-02 Thread Tvrtko Ursulin



On 28/02/2022 19:17, John Harrison wrote:

On 2/28/2022 07:32, Tvrtko Ursulin wrote:

On 25/02/2022 19:03, John Harrison wrote:

On 2/25/2022 10:29, Tvrtko Ursulin wrote:

On 25/02/2022 18:01, John Harrison wrote:

On 2/25/2022 09:39, Tvrtko Ursulin wrote:

On 25/02/2022 17:11, John Harrison wrote:

On 2/25/2022 08:36, Tvrtko Ursulin wrote:

On 24/02/2022 20:02, John Harrison wrote:

On 2/23/2022 04:00, Tvrtko Ursulin wrote:

On 23/02/2022 02:22, John Harrison wrote:

On 2/22/2022 01:53, Tvrtko Ursulin wrote:

On 18/02/2022 21:33, john.c.harri...@intel.com wrote:

From: John Harrison 

Compute workloads are inherently not pre-emptible on 
current hardware.
Thus the pre-emption timeout was disabled as a workaround 
to prevent
unwanted resets. Instead, the hang detection was left to 
the heartbeat
and its (longer) timeout. This is undesirable with GuC 
submission as
the heartbeat is a full GT reset rather than a per engine 
reset and so
is much more destructive. Instead, just bump the 
pre-emption timeout


Can we have a feature request to allow asking GuC for an 
engine reset?

For what purpose?


To allow "stopped heartbeat" to reset the engine, however..

GuC manages the scheduling of contexts across engines. With 
virtual engines, the KMD has no knowledge of which engine a 
context might be executing on. Even without virtual engines, 
the KMD still has no knowledge of which context is currently 
executing on any given engine at any given time.


There is a reason why hang detection should be left to the 
entity that is doing the scheduling. Any other entity is 
second guessing at best.


The reason for keeping the heartbeat around even when GuC 
submission is enabled is for the case where the KMD/GuC have 
got out of sync with either other somehow or GuC itself has 
just crashed. I.e. when no submission at all is working and 
we need to reset the GuC itself and start over.


.. I wasn't really up to speed to know/remember heartbeats are 
nerfed already in GuC mode.
Not sure what you mean by that claim. Engine resets are handled 
by GuC because GuC handles the scheduling. You can't do the 
former if you aren't doing the latter. However, the heartbeat 
is still present and is still the watchdog by which engine 
resets are triggered. As per the rest of the submission 
process, the hang detection and recovery is split between i915 
and GuC.


I meant that "stopped heartbeat on engine XXX" can only do a 
full GPU reset on GuC.
I mean that there is no 'stopped heartbeat on engine XXX' when 
i915 is not handling the recovery part of the process.


H?

static void
reset_engine(struct intel_engine_cs *engine, struct i915_request *rq)
{
if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
    show_heartbeat(rq, engine);

if (intel_engine_uses_guc(engine))
    /*
 * GuC itself is toast or GuC's hang detection
 * is disabled. Either way, need to find the
 * hang culprit manually.
 */
    intel_guc_find_hung_context(engine);

intel_gt_handle_error(engine->gt, engine->mask,
  I915_ERROR_CAPTURE,
  "stopped heartbeat on %s",
  engine->name);
}

How there is no "stopped hearbeat" in guc mode? From this code it 
certainly looks there is.
Only when the GuC is toast and it is no longer an engine reset but 
a full GT reset that is required. So technically, it is not a 
'stopped heartbeat on engine XXX' it is 'stopped heartbeat on GT#'.




You say below heartbeats are going in GuC mode. Now I totally 
don't understand how they are going but there is allegedly no 
"stopped hearbeat".
Because if GuC is handling the detection and recovery then i915 
will not reach that point. GuC will do the engine reset and start 
scheduling the next context before the heartbeat period expires. So 
the notification will be a G2H about a specific context being reset 
rather than the i915 notification about a stopped heartbeat.






intel_gt_handle_error(engine->gt, engine->mask,
  I915_ERROR_CAPTURE,
  "stopped heartbeat on %s",
  engine->name);

intel_gt_handle_error:

/*
 * Try engine reset when available. We fall back to full 
reset if

 * single reset fails.
 */
if (!intel_uc_uses_guc_submission(>->uc) &&
    intel_has_reset_engine(gt) && !intel_gt_is_wedged(gt)) {
    local_bh_disable();
    for_each_engine_masked(engine, gt, engine_mask, tmp) {

You said "However, the heartbeat is still present and is still 
the watchdog by which engine resets are triggered", now I don't 
know what you meant by this. It actually triggers a single 
engine reset in GuC mode? Where in code does that happen if this 
block above shows it not taking the engine reset path?

i915 sends down the per engine pulse.
GuC schedules the pulse
GuC attempts to pre-empt the currently active context
GuC detects the pre-emption timeout
GuC resets the engine

The fundamental process is exactl

Re: [PATCH v1 3/3] drm/panel : innolux-ej030na and abt-y030xx067a : add .enable and .disable

2022-03-02 Thread Paul Cercueil

Hi Christophe,

Le mar., mars 1 2022 at 16:31:22 +0100, Christophe Branchereau 
 a écrit :

Following the introduction of bridge_atomic_enable in the ingenic
drm driver, the crtc is enabled between .prepare and .enable, if
it exists.

Add it so the backlight is only enabled after the crtc is, to avoid
graphical issues.

Signed-off-by: Christophe Branchereau 
---
 drivers/gpu/drm/panel/panel-abt-y030xx067a.c  | 23 --
 drivers/gpu/drm/panel/panel-innolux-ej030na.c | 31 
---

 2 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c 
b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c

index f043b484055b..b5736344e3ec 100644
--- a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
+++ b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
@@ -183,8 +183,6 @@ static int y030xx067a_prepare(struct drm_panel 
*panel)

goto err_disable_regulator;
}

-   msleep(120);
-
return 0;

 err_disable_regulator:
@@ -202,6 +200,25 @@ static int y030xx067a_unprepare(struct drm_panel 
*panel)

return 0;
 }

+static int y030xx067a_enable(struct drm_panel *panel)
+{
+   if (panel->backlight) {
+   /* Wait for the picture to be ready before enabling backlight */
+   msleep(120);
+   }
+
+   return 0;
+}
+
+static int y030xx067a_disable(struct drm_panel *panel)
+{
+   struct y030xx067a *priv = to_y030xx067a(panel);
+
+   regmap_clear_bits(priv->map, 0x06, REG06_XPSAVE);


Shouldn't that be balanced by a regmap_set_bits() in the .enable() 
function?


Cheers,
-Paul


+
+   return 0;
+}
+
 static int y030xx067a_get_modes(struct drm_panel *panel,
struct drm_connector *connector)
 {
@@ -239,6 +256,8 @@ static int y030xx067a_get_modes(struct drm_panel 
*panel,

 static const struct drm_panel_funcs y030xx067a_funcs = {
.prepare= y030xx067a_prepare,
.unprepare  = y030xx067a_unprepare,
+   .enable = y030xx067a_enable,
+   .disable= y030xx067a_disable,
.get_modes  = y030xx067a_get_modes,
 };

diff --git a/drivers/gpu/drm/panel/panel-innolux-ej030na.c 
b/drivers/gpu/drm/panel/panel-innolux-ej030na.c

index c558de3f99be..6de7370185cd 100644
--- a/drivers/gpu/drm/panel/panel-innolux-ej030na.c
+++ b/drivers/gpu/drm/panel/panel-innolux-ej030na.c
@@ -80,8 +80,6 @@ static const struct reg_sequence 
ej030na_init_sequence[] = {

{ 0x47, 0x08 },
{ 0x48, 0x0f },
{ 0x49, 0x0f },
-
-   { 0x2b, 0x01 },
 };

 static int ej030na_prepare(struct drm_panel *panel)
@@ -109,8 +107,6 @@ static int ej030na_prepare(struct drm_panel 
*panel)

goto err_disable_regulator;
}

-   msleep(120);
-
return 0;

 err_disable_regulator:
@@ -128,6 +124,31 @@ static int ej030na_unprepare(struct drm_panel 
*panel)

return 0;
 }

+static int ej030na_enable(struct drm_panel *panel)
+{
+   struct ej030na *priv = to_ej030na(panel);
+
+   /* standby off */
+   regmap_write(priv->map, 0x2b, 0x01);
+
+   if (panel->backlight) {
+   /* Wait for the picture to be ready before enabling backlight */
+   msleep(120);
+   }
+
+   return 0;
+}
+
+static int ej030na_disable(struct drm_panel *panel)
+{
+   struct ej030na *priv = to_ej030na(panel);
+
+   /* standby on */
+   regmap_write(priv->map, 0x2b, 0x00);
+
+   return 0;
+}
+
 static int ej030na_get_modes(struct drm_panel *panel,
 struct drm_connector *connector)
 {
@@ -165,6 +186,8 @@ static int ej030na_get_modes(struct drm_panel 
*panel,

 static const struct drm_panel_funcs ej030na_funcs = {
.prepare= ej030na_prepare,
.unprepare  = ej030na_unprepare,
+   .enable = ej030na_enable,
+   .disable= ej030na_disable,
.get_modes  = ej030na_get_modes,
 };

--
2.34.1






Re: [PATCH v7 10/24] drm/rockchip: dw_hdmi: Add support for hclk

2022-03-02 Thread Sascha Hauer
On Tue, Mar 01, 2022 at 01:39:31PM +, Robin Murphy wrote:
> On 2022-02-28 14:19, Sascha Hauer wrote:
> > On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
> > > On Fri, Feb 25, 2022 at 12:41:23PM +, Robin Murphy wrote:
> > > > On 2022-02-25 11:10, Dmitry Osipenko wrote:
> > > > > 25.02.2022 13:49, Sascha Hauer пишет:
> > > > > > On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> > > > > > > 25.02.2022 10:51, Sascha Hauer пишет:
> > > > > > > > The rk3568 HDMI has an additional clock that needs to be 
> > > > > > > > enabled for the
> > > > > > > > HDMI controller to work. The purpose of that clock is not 
> > > > > > > > clear. It is
> > > > > > > > named "hclk" in the downstream driver, so use the same name.
> > > > > > > > 
> > > > > > > > Signed-off-by: Sascha Hauer 
> > > > > > > > ---
> > > > > > > > 
> > > > > > > > Notes:
> > > > > > > >   Changes since v5:
> > > > > > > >   - Use devm_clk_get_optional rather than devm_clk_get
> > > > > > > > 
> > > > > > > >drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 
> > > > > > > > 
> > > > > > > >1 file changed, 16 insertions(+)
> > > > > > > > 
> > > > > > > > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
> > > > > > > > b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > > > index fe4f9556239ac..c6c00e8779ab5 100644
> > > > > > > > --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > > > +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > > > @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> > > > > > > > const struct rockchip_hdmi_chip_data *chip_data;
> > > > > > > > struct clk *ref_clk;
> > > > > > > > struct clk *grf_clk;
> > > > > > > > +   struct clk *hclk_clk;
> > > > > > > > struct dw_hdmi *hdmi;
> > > > > > > > struct regulator *avdd_0v9;
> > > > > > > > struct regulator *avdd_1v8;
> > > > > > > > @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct 
> > > > > > > > rockchip_hdmi *hdmi)
> > > > > > > > return PTR_ERR(hdmi->grf_clk);
> > > > > > > > }
> > > > > > > > +   hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, 
> > > > > > > > "hclk");
> > > > > > > > +   if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> > > > > > > 
> > > > > > > Have you tried to investigate the hclk? I'm still thinking that's 
> > > > > > > not
> > > > > > > only HDMI that needs this clock and then the hardware description
> > > > > > > doesn't look correct.
> > > > > > 
> > > > > > I am still not sure what you mean. Yes, it's not only the HDMI that
> > > > > > needs this clock. The VOP2 needs it as well and the driver handles 
> > > > > > that.
> > > > > 
> > > > > I'm curious whether DSI/DP also need that clock to be enabled. If they
> > > > > do, then you aren't modeling h/w properly AFAICS.
> > > > 
> > > > Assuming nobody at Rockchip decided to make things needlessly 
> > > > inconsistent
> > > > with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
> > > > interface. Usually, if that affected anything other than accessing VOP
> > > > registers, indeed it would smell of something being wrong in the clock 
> > > > tree,
> > > > but in this case I'd also be suspicious of whether it might have ended 
> > > > up
> > > > clocking related GRF registers as well (either directly, or indirectly 
> > > > via
> > > > some gate that the clock driver hasn't modelled yet).
> > > 
> > > Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
> > > hanging when HCLK_VOP is disabled by disabling that clock via sysfs
> > > using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
> > > of that units can't be accessed. However, when I disable HCLK_VOP by
> > > directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
> > > accessing VOP registers hangs, the other units stay functional.
> > > So it seems it must be the parent clock which must be enabled. The
> > > parent clock is hclk_vo. This clock should be handled as part of the
> > > RK3568_PD_VO power domain:
> > > 
> > >   power-domain@RK3568_PD_VO {
> > >  reg = ;
> > >  clocks = <&cru HCLK_VO>,
> > >   <&cru PCLK_VO>,
> > >   <&cru ACLK_VOP_PRE>;
> > >   pm_qos = <&qos_hdcp>,
> > ><&qos_vop_m0>,
> > ><&qos_vop_m1>;
> > >   #power-domain-cells = <0>;
> > >  };
> > 
> > Forget this. The clocks in this node are only enabled during enabling or
> > disabling the power domain, they are disabled again immediately afterwards.
> > 
> > OK, I need HCLK_VO to access the HDMI registers. I verified that by
> > disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
> > HDMI registers become inaccessible then. This means I'll replace
> > HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?
> 
> Well, it'

Re: [PATCH v2 2/8] drm: bridge: nwl-dsi: Switch to devm_drm_of_get_bridge

2022-03-02 Thread Guido Günther
Hi,
On Tue, Mar 01, 2022 at 07:42:41PM +0530, Jagan Teki wrote:
> devm_drm_of_get_bridge is capable of looking up the downstream
> bridge and panel and trying to add a panel bridge if the panel
> is found.
> 
> Replace explicit finding calls with devm_drm_of_get_bridge.
> 
> Cc: Guido Günther 
> Signed-off-by: Jagan Teki 
> ---
> Changes for v2:
> - split the patch
> 
>  drivers/gpu/drm/bridge/nwl-dsi.c | 18 +++---
>  1 file changed, 3 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c 
> b/drivers/gpu/drm/bridge/nwl-dsi.c
> index 30aacd939dc3..c9e108a7eca2 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -916,22 +916,10 @@ static int nwl_dsi_bridge_attach(struct drm_bridge 
> *bridge,
>  {
>   struct nwl_dsi *dsi = bridge_to_dsi(bridge);
>   struct drm_bridge *panel_bridge;
> - struct drm_panel *panel;
> - int ret;
> -
> - ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, &panel,
> -   &panel_bridge);
> - if (ret)
> - return ret;
> -
> - if (panel) {
> - panel_bridge = drm_panel_bridge_add(panel);
> - if (IS_ERR(panel_bridge))
> - return PTR_ERR(panel_bridge);
> - }
>  
> - if (!panel_bridge)
> - return -EPROBE_DEFER;
> + panel_bridge = devm_drm_of_get_bridge(dsi->dev, dsi->dev->of_node, 1, 
> 0);
> + if (IS_ERR(panel_bridge))
> + return PTR_ERR(panel_bridge);
>  
>   return drm_bridge_attach(bridge->encoder, panel_bridge, bridge, flags);
>  }

Reviewed-by: Guido Günther 

Thanks,
 -- Guido

> -- 
> 2.25.1
> 


Re: MSM8960: gpu/drm/dp/drm_dp.c:59:27: warning: array subscript 10 is outside, array bounds of 'const u8[6]'

2022-03-02 Thread Jani Nikula
On Tue, 01 Mar 2022, Rudraksha Gupta  wrote:
> Hi all,
>
>
> I am getting this warning when compiling the kernel for the MSM8960 with 
> this defconfig: 
> https://raw.githubusercontent.com/apq8064-mainline/linux/qcom-apq8064-next/arch/arm/configs/qcom_apq8064_defconfig
>
>
> Warning:
>
> ../drivers/gpu/drm/dp/drm_dp.c: In function 
> 'drm_dp_get_adjust_request_post_cursor':
> ../drivers/gpu/drm/dp/drm_dp.c:59:27: warning: array subscript 10 is 
> outside array bounds of 'const u8[6]' {aka 'const unsigned char[6]'} 
> [-Warray-bounds]
>     59 | return link_status[r - DP_LANE0_1_STATUS];
>    |    ~~~^~~
> ../drivers/gpu/drm/dp/drm_dp.c:210:51: note: while referencing 'link_status'
>    210 | u8 drm_dp_get_adjust_request_post_cursor(const u8 
> link_status[DP_LINK_STATUS_SIZE],
>    | ~^~~~
>

Please see 
https://lore.kernel.org/r/20220225035610.2552144-3-keesc...@chromium.org

BR,
Jani.


-- 
Jani Nikula, Intel Open Source Graphics Center


Re: [PATCH] drm/bridge: nwl-dsi: Remove superfluous write to NWL_DSI_IRQ_MASK register

2022-03-02 Thread Guido Günther
Hi Liu,
On Wed, Feb 16, 2022 at 04:58:42PM +0800, Liu Ying wrote:
> To initialize register NWL_DSI_IRQ_MASK, it's enough to write it
> only once in function nwl_dsi_init_interrupts().
> 
> Signed-off-by: Liu Ying 
> ---
>  drivers/gpu/drm/bridge/nwl-dsi.c | 14 +-
>  1 file changed, 5 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c 
> b/drivers/gpu/drm/bridge/nwl-dsi.c
> index af07eeb47ca0..fcc4a2889ad4 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -333,17 +333,13 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
>  
>  static int nwl_dsi_init_interrupts(struct nwl_dsi *dsi)
>  {
> - u32 irq_enable;
> -
> - nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, 0x);
> - nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7);
> -
> - irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK |
> - NWL_DSI_RX_PKT_HDR_RCVD_MASK |
> - NWL_DSI_TX_FIFO_OVFLW_MASK |
> - NWL_DSI_HS_TX_TIMEOUT_MASK);
> + u32 irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK |
> + NWL_DSI_RX_PKT_HDR_RCVD_MASK |
> + NWL_DSI_TX_FIFO_OVFLW_MASK |
> + NWL_DSI_HS_TX_TIMEOUT_MASK);
>  
>   nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, irq_enable);
> + nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7);

Works fine here. I thought it was due to some hw quirk but can't find
any note in it so:

Reviewed-by: Guido Günther 

Thanks,
 -- Guido

>  
>   return nwl_dsi_clear_error(dsi);
>  }
> -- 
> 2.25.1
> 


Re: linux-next: build warning after merge of the drm tree

2022-03-02 Thread Stephen Rothwell
Hi Hans,

On Wed, 2 Mar 2022 11:32:37 +0100 Hans de Goede  wrote:
>
> On 3/2/22 02:34, Stephen Rothwell wrote:
> > Hi all,
> > 
> > On Wed, 2 Feb 2022 09:38:37 +0100 Hans de Goede  
> > wrote:  
> >>
> >> On 2/2/22 05:03, Stephen Rothwell wrote:  
> >>>
> >>> On Wed, 2 Feb 2022 15:02:01 +1100 Stephen Rothwell 
> >>>  wrote:
> 
>  After merging the drm tree, today's linux-next build (htmldocs) produced
>  this warning:
> 
>  drivers/gpu/drm/drm_privacy_screen.c:X: warning: Function parameter or 
>  member 'data' not described in 'drm_privacy_screen_register'
> >>>
> >>> Actually:
> >>>
> >>> drivers/gpu/drm/drm_privacy_screen.c:392: warning: Function parameter or 
> >>> member 'data' not described in 'drm_privacy_screen_register'
> >>
> >> Thank you for reporting this, I will prepare a patch fixing this.  
> > 
> > I am still seeing this warning.  
> 
> Weird, this should be fixed by:
> 
> https://cgit.freedesktop.org/drm-misc/commit/?id=ccbeca4ca04302d129602093c8d611065e3f7958
> 
> Which was added to the "drm-misc-next-2022-02-23" drm-misc tag/pull-req 7 
> days ago,
> which was merged into drm-next 6 days ago ?
> 
> I just reverted that did a make htmldocs and got the warning, then re-applied 
> and
> the warning was gone...

As I said in my other reply, the drm tree has had build problems until
today and so it has been only partly included in linux-next.  I can
confirm that the warning is gone in today's tree.

-- 
Cheers,
Stephen Rothwell


pgp7ZbMWhN2t7.pgp
Description: OpenPGP digital signature


Re: [PATCH] drm/i915: Depend on !PREEMPT_RT.

2022-03-02 Thread Tvrtko Ursulin



On 01/03/2022 15:13, Sebastian Andrzej Siewior wrote:

On 2022-03-01 14:27:18 [+], Tvrtko Ursulin wrote:

you see:
 0003-drm-i915-Use-preempt_disable-enable_rt-where-recomme.patch
 0004-drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch


Two for the display folks.


 0005-drm-i915-Don-t-check-for-atomic-context-on-PREEMPT_R.patch


What do preempt_disable/enable do on PREEMPT_RT? Thinking if instead the
solution could be to always force the !ATOMIC path (for the whole
_wait_for_atomic macro) on PREEMPT_RT.


Could be one way to handle it. But please don't disable preemption and
or interrupts for longer period of time as all of it increases the
overall latency.


I am looking for your guidance of what is the correct thing here.

Main purpose of this macro on the i915 side is to do short waits on GPU 
registers changing post write from spin-locked sections. But there were 
rare cases when very short waits were needed from unlocked sections, 
shorter than 10us (which is AFAIR what usleep_range documents should be 
a lower limit). Which is why non-atomic path was added to the macro. 
That path uses preempt_disable/enable so it can use local_clock().


All this may, or may not be, compatible with PREEMPT_RT to start with?

Or question phrased differently, how we should implement the <10us waits 
from non-atomic sections under PREEMPT_RT?



Side note: All of these patches is a collection over time. I personally
have only a single i7-sandybridge with i915 and here I don't really
enter all the possible paths here. People report, I patch and look
around and then they are quiet so I assume that it is working.


 0006-drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch


If the issue is only with certain trace points why disable all?


It is a class and it is easier that way.


 0007-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch


Didn't quite fully understand, why is this not fixable? Especially thinking
if the option of not blanket disabling all tracepoints in the previous
patch.


The problem is that you can't acquire that lock from within that
trace-point on PREEMPT_RT. On !RT it is possible but it is also
problematic because LOCKDEP does not see possible dead locks unless that
trace-point is enabled.


Oh I meant could the include ordering problem be fixed differently?

"""
[PATCH 07/10] drm/i915: skip DRM_I915_LOW_LEVEL_TRACEPOINTS with
 NOTRACE

The order of the header files is important. If this header file is
included after tracepoint.h was included then the NOTRACE here becomes a
nop. Currently this happens for two .c files which use the tracepoitns
behind DRM_I915_LOW_LEVEL_TRACEPOINTS.
"""

Like these two .c files - can order of includes just be changed in them?



I've been talking to Steven (after
https://lkml.kernel.org/r/20211214115837.6f33a...@gandalf.local.home)
and he wants to come up with something where you can pass a lock as
argument to the tracing-API. That way the lock can be acquired before
the trace event is invoked and lockdep will see it even if the trace
event is disabled.
So there is an idea how to get it to work eventually without disabling
it in the long term.

Making the register a raw_spinlock_t would solve problem immediately but
I am a little worried given the increased latency in a quick test:
https://lore.kernel.org/all/20211006164628.s2mtsdd2jdbfy...@linutronix.de/

also, this one single hardware but the upper limit atomic-polls is high.


 0008-drm-i915-gt-Queue-and-wait-for-the-irq_work-item.patch


Not sure about why cond_resched was put between irq_work_queue and
irq_work_sync - would it not be like-for-like change to have the two
together?


maybe it loops for a while and an additional scheduling would be nice.


Commit message makes me think _queue already starts the handler on
x86 at least.


Yes, irq_work_queue() triggers the IRQ right away on x86,
irq_work_sync() would wait for it to happen in case it did not happen.
On architectures which don't provide an IRQ-work interrupt, it is
delayed to the HZ tick timer interrupt. So this serves also as an
example in case someone want to copy the code ;)


My question wasn't why is there a need_resched() in there, but why is 
the patch:


+   irq_work_queue(&b->irq_work);
cond_resched();
+   irq_work_sync(&b->irq_work);

And not:

+   irq_work_queue(&b->irq_work);
+   irq_work_sync(&b->irq_work);
cond_resched();

To preserve like for like, if my understanding of the commit message was 
correct.





 0009-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch


I think this is okay. The part after the unlock is serialized by the tasklet
already.

Slight doubt due the comment:

   local_irq_enable(); /* flush irq_work (e.g. breadcrumb enabling) */

Makes me want to think about it harder but not now.


Clark reported it and confirmed that the warning is gone on RT and
everything appears t

Re: [PATCH 1/9] dt-bindings: mxsfb: Add compatible for i.MX8MP

2022-03-02 Thread Lucas Stach
Am Mittwoch, dem 02.03.2022 um 17:41 +0800 schrieb Liu Ying:
> On Wed, 2022-03-02 at 10:23 +0100, Lucas Stach wrote:
> > Am Mittwoch, dem 02.03.2022 um 03:54 +0100 schrieb Marek Vasut:
> > > On 3/1/22 14:18, Lucas Stach wrote:
> > > > Am Dienstag, dem 01.03.2022 um 07:03 -0600 schrieb Adam Ford:
> > > > > On Tue, Mar 1, 2022 at 5:05 AM Lucas Stach  
> > > > > wrote:
> > > > > > Am Dienstag, dem 01.03.2022 um 11:19 +0100 schrieb Marek Vasut:
> > > > > > > On 3/1/22 11:04, Lucas Stach wrote:
> > > > > > > 
> > > > > > > Hi,
> > > > > > > 
> > > > > > > [...]
> > > > > > > 
> > > > > > > > > Given the two totally different IPs, I don't see bugs of IP 
> > > > > > > > > control
> > > > > > > > > logics should be fixed for both drivers. Naturally, the two 
> > > > > > > > > would
> > > > > > > > > diverge due to different HWs. Looking at Patch 9/9, it 
> > > > > > > > > basically
> > > > > > > > > squashes code to control LCDIFv3 into the mxsfb drm driver 
> > > > > > > > > with
> > > > > > > > > 'if/else' checks(barely no common control code), which is 
> > > > > > > > > hard to
> > > > > > > > > maintain and not able to achieve good scalability for both 
> > > > > > > > > 'LCDIFv3'
> > > > > > > > > and 'LCDIF'.
> > > > > > > > 
> > > > > > > > I tend to agree with Liu here. Writing a DRM driver isn't that 
> > > > > > > > much
> > > > > > > > boilerplate anymore with all the helpers we have available in 
> > > > > > > > the
> > > > > > > > framework today.
> > > > > > > 
> > > > > > > I did write a separate driver for this IP before I spent time 
> > > > > > > merging
> > > > > > > them into single driver, that's when I realized a single driver 
> > > > > > > is much
> > > > > > > better and discarded the separate driver idea.
> > > > > > > 
> > > > > > > > The IP is so different from the currently supported LCDIF 
> > > > > > > > controllers
> > > > > > > > that I think trying to support this one in the existing driver 
> > > > > > > > actually
> > > > > > > > increases the chances to break something when modifying the 
> > > > > > > > driver in
> > > > > > > > the future. Not everyone is able to test all LCDIF versions. My 
> > > > > > > > vote is
> > > > > > > > on having a separate driver for the i.MX8MP LCDIF.
> > > > > > > 
> > > > > > > If you look at both controllers, it is clear it is still the LCDIF
> > > > > > > behind, even the CSC that is bolted on would suggest that.
> > > > > > 
> > > > > > Yes, but from a driver PoV what you care about is not really the
> > > > > > hardware blocks used to implement something, but the programming 
> > > > > > model,
> > > > > > i.e. the register interface exposed to software.
> > > > > > 
> > > > > > > I am also not happy when I look at the amount of duplication a 
> > > > > > > separate
> > > > > > > driver would create, it will be some 50% of the code that would 
> > > > > > > be just
> > > > > > > duplicated.
> > > > > > > 
> > > > > > Yea, the duplicated code is still significant, as the HW itself is 
> > > > > > so
> > > > > > simple. However, if you find yourself in the situation where 
> > > > > > basically
> > > > > > every actual register access in the driver ends up being in a "if 
> > > > > > (some
> > > > > > HW rev) ... " clause, i still think it would be better to have a
> > > > > > separate driver, as the programming interface is just different.
> > > > > 
> > > > > I tend to agree with Marek on this one.  We have an instance where the
> > > > > blk-ctrl and the GPC driver between 8m, mini, nano, plus are close,
> > > > > but different enough where each SoC has it's own set of tables and
> > > > > some checks.   Lucas created the framework, and others adapted it for
> > > > > various SoC's.  If there really is nearly 50% common code for the
> > > > > LCDIF, why not either leave the driver as one or split the common code
> > > > > into its own driver like lcdif-common and then have smaller drivers
> > > > > that handle their specific variations.
> > > > 
> > > > I don't know exactly how the standalone driver looks like, but I guess
> > > > the overlap is not really in any real HW specific parts, but the common
> > > > DRM boilerplate, so there isn't much point in creating a common lcdif
> > > > driver.
> > > 
> > > The mxsfb currently has 1280 LoC as of patch 8/9 of this series. Of 
> > > that, there is some 400 LoC which are specific to old LCDIF and this 
> > > patch adds 380 LoC for the new LCDIF. So that's 800 LoC or ~60% of 
> > > shared boilerplate that would be duplicated .
> > 
> > That is probably ignoring the fact that the 8MP LCDIF does not support
> > any overlays, so it could use the drm_simple_display_pipe
> > infrastructure to reduce the needed boilerplate.
> 
> The drm_simple_display_pipe infrastructure is probably too simple for
> i.MX8MP LCDIF, since it uses one only crtc for one drm device. i.MX8MP
> embeds *three* LCDIF instances to support MIPI DSI, LVDS and HDMI
> outputs respectively. To use that infrastructure means there 

Re: [PATCH v2 8/8] drm: bridge: anx7625: Switch to devm_drm_of_get_bridge

2022-03-02 Thread Linus Walleij
On Wed, Mar 2, 2022 at 5:37 AM Jagan Teki  wrote:
> On Wed, Mar 2, 2022 at 4:50 AM Linus Walleij  wrote:
> >
> > On Tue, Mar 1, 2022 at 3:13 PM Jagan Teki  
> > wrote:
> >
> > > +   bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
> > > +   if (IS_ERR(bridge)) {
> > > +   dev_err(dev, "error to get bridge\n");
> > > +   return PTR_ERR(bridge);
> > > }
> > >
> > > d->bridge_out = bridge;
> >
> > Also notice how this bridge gets used in other places:
> >
> > struct drm_connector *connector = drm_panel_bridge_connector(mcde->bridge);
>
> mcde->bridge bridge is the current bridge pointer it cannot affect
> this change. d->bridge_out is what we are finding of the downstream
> bridge.

Sorry I confused things.

Got lost in my own code :/

The bridge in the other file is for DPI obviously...
I should rename it dpi_panel_bridge.

> > Since you deleted:
> >
> > -   } else if (bridge) {
> > -   /* TODO: AV8100 HDMI encoder goes here for example */
> > -   dev_info(dev, "connected to non-panel bridge 
> > (unsupported)\n");
> > -   return -ENODEV;
>
> So, this means mcde dsi can support if the downstream bridge is the
> panel not if the downstream bridge is the next bridge. With
> devm_drm_of_get_bridge we cannot find that diff. Identifying the
> panel-bridge with some name pointer during panel_bridge_add might
> solve this, not sure that is proper way to do that?

I'd say leave it, as the DSI bridge (bridge_out) doesn't really care
about this being a panel or not. A further bridge down the chain
should "just work" (famous last words).

Just make sure we properly remove bridge_out in unbind call.

Yours,
Linus Walleij


[PATCH] drm/bridge: anx7625: Set downstream sink into normal status

2022-03-02 Thread Xin Ji
As downstream sink was set into standby mode while bridge disabled,
this patch used for setting downstream sink into normal status
while enable bridge.

Signed-off-by: Xin Ji 
---
 drivers/gpu/drm/bridge/analogix/anx7625.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 9aab879a8851..963eaf73ecab 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -919,12 +919,20 @@ static void anx7625_dp_start(struct anx7625_data *ctx)
 {
int ret;
struct device *dev = &ctx->client->dev;
+   u8 data;
 
if (!ctx->display_timing_valid) {
DRM_DEV_ERROR(dev, "mipi not set display timing yet.\n");
return;
}
 
+   dev_info(dev, "set downstream sink into normal\n");
+   /* Downstream sink enter into normal mode */
+   data = 1;
+   ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, 0x000600, 1, &data);
+   if (ret < 0)
+   dev_err(dev, "IO error : set sink into normal mode fail\n");
+
/* Disable HDCP */
anx7625_write_and(ctx, ctx->i2c.rx_p1_client, 0xee, 0x9f);
 
-- 
2.25.1



Re: [PATCH] drm/panfrost: cleanup comments

2022-03-02 Thread Tom Rix



On 3/2/22 1:09 AM, Steven Price wrote:

On 01/03/2022 12:43, t...@redhat.com wrote:

From: Tom Rix 

For spdx
change tab to space delimiter
Use // for *.c

Replacements
commited to committed, use multiline comment style
regsiters to registers
initialze to initialize

Signed-off-by: Tom Rix 

Thanks, most of the changes look reasonable (although I've never
understood the reason for using // for SPDX comments), but there's one
below that I think needs rethinking.


---
  drivers/gpu/drm/panfrost/panfrost_drv.c  | 2 +-
  drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c | 2 +-
  drivers/gpu/drm/panfrost/panfrost_issues.h   | 6 --
  drivers/gpu/drm/panfrost/panfrost_mmu.c  | 2 +-
  drivers/gpu/drm/panfrost/panfrost_regs.h | 2 +-
  5 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 96bb5a4656278..94b6f0a19c83a 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -562,7 +562,7 @@ static int panfrost_probe(struct platform_device *pdev)
  
  	pfdev->coherent = device_get_dma_attr(&pdev->dev) == DEV_DMA_COHERENT;
  
-	/* Allocate and initialze the DRM device. */

+   /* Allocate and initialize the DRM device. */
ddev = drm_dev_alloc(&panfrost_drm_driver, &pdev->dev);
if (IS_ERR(ddev))
return PTR_ERR(ddev);
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c 
b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
index b0142341e2235..77e7cb6d1ae3b 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
  /* Copyright (C) 2019 Arm Ltd.
   *
   * Based on msm_gem_freedreno.c:
diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h 
b/drivers/gpu/drm/panfrost/panfrost_issues.h
index 8e59d765bf19f..4e7cf979ee67a 100644
--- a/drivers/gpu/drm/panfrost/panfrost_issues.h
+++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
@@ -13,8 +13,10 @@
   * to care about.
   */
  enum panfrost_hw_issue {
-   /* Need way to guarantee that all previously-translated memory accesses
-* are commited */
+   /*
+* Need way to guarantee that all previously-translated memory accesses
+* are committed
+*/

This file has a whole load of multiline comments that don't technically
follow the coding style. Fixing just one comment makes the file
inconsistent. Note we recently had a discussion about this[1] and
decided to leave the comment style as is. And I have to admit in this
instance avoiding the extra mostly-blank lines makes the list easier to
read. The typo fix is obviously welcomed though!


I'll switch this back in a respin.

Thanks

Tom




[1] https://lore.kernel.org/r/c7331489-ad04-0f35-224e-164f144fb819%40arm.com


HW_ISSUE_6367,
  
  	/* On job complete with non-done the cache is not flushed */

diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index 39562f2d11a47..d3f82b26a631d 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier:GPL-2.0
+// SPDX-License-Identifier: GPL-2.0
  /* Copyright 2019 Linaro, Ltd, Rob Herring  */
  
  #include 

diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h 
b/drivers/gpu/drm/panfrost/panfrost_regs.h
index 6c5a11ef1ee87..efe4b75149d35 100644
--- a/drivers/gpu/drm/panfrost/panfrost_regs.h
+++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
@@ -292,7 +292,7 @@
  #define AS_FAULTADDRESS_LO(as)(MMU_AS(as) + 0x20) /* (RO) 
Fault Address for address space n, low word */
  #define AS_FAULTADDRESS_HI(as)(MMU_AS(as) + 0x24) /* (RO) 
Fault Address for address space n, high word */
  #define AS_STATUS(as) (MMU_AS(as) + 0x28) /* (RO) Status 
flags for address space n */
-/* Additional Bifrost AS regsiters */
+/* Additional Bifrost AS registers */
  #define AS_TRANSCFG_LO(as)(MMU_AS(as) + 0x30) /* (RW) Translation 
table configuration for address space n, low word */
  #define AS_TRANSCFG_HI(as)(MMU_AS(as) + 0x34) /* (RW) Translation 
table configuration for address space n, high word */
  #define AS_FAULTEXTRA_LO(as)  (MMU_AS(as) + 0x38) /* (RO) Secondary 
fault address for address space n, low word */




Re: [PATCH v4 1/9] dt-bindings: host1x: Add iommu-map property

2022-03-02 Thread Mikko Perttunen

On 3/1/22 20:12, Robin Murphy wrote:

On 2022-03-01 16:14, cyn...@kapsi.fi wrote:

From: Mikko Perttunen 

Add schema information for specifying context stream IDs. This uses
the standard iommu-map property.

Signed-off-by: Mikko Perttunen 
---
v3:
* New patch
v4:
* Remove memory-contexts subnode.
---
  .../bindings/display/tegra/nvidia,tegra20-host1x.yaml    | 5 +
  1 file changed, 5 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml 
b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml 


index 4fd513efb0f7..0adeb03b9e3a 100644
--- 
a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml 

+++ 
b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml 


@@ -144,6 +144,11 @@ allOf:
  reset-names:
    maxItems: 1
+    iommu-map:
+  description: Specification of stream IDs available for 
memory context device
+    use. Should be a mapping of IDs 0..n to IOMMU entries 
corresponding to


Nit: maybe "context IDs 0..n" for maximum possible clarity?


I left it at "IDs" since there is no "context ID" or similar concept in 
the hardware, so I thought to leave it just as a kind of an 'abstract ID 
as used in iommu-map property'.




Either way, though, I'm happy that if the simplest and most 
straightforward approach works, then it's the best choice.


I am happy as well, this is certainly much cleaner than the mess in the 
downstream driver :)




Reviewed-by: Robin Murphy 

Cheers,
Robin.


Thanks!
Mikko




+    usable stream IDs.
+
    required:
  - reg-names




Re: [PATCH] drm/i915: Depend on !PREEMPT_RT.

2022-03-02 Thread Sebastian Andrzej Siewior
On 2022-03-02 11:42:35 [+], Tvrtko Ursulin wrote:
> > > >  0005-drm-i915-Don-t-check-for-atomic-context-on-PREEMPT_R.patch
> > > 
> > > What do preempt_disable/enable do on PREEMPT_RT? Thinking if instead the
> > > solution could be to always force the !ATOMIC path (for the whole
> > > _wait_for_atomic macro) on PREEMPT_RT.
> > 
> > Could be one way to handle it. But please don't disable preemption and
> > or interrupts for longer period of time as all of it increases the
> > overall latency.
> 
> I am looking for your guidance of what is the correct thing here.
> 
> Main purpose of this macro on the i915 side is to do short waits on GPU
> registers changing post write from spin-locked sections. But there were rare
> cases when very short waits were needed from unlocked sections, shorter than
> 10us (which is AFAIR what usleep_range documents should be a lower limit).
> Which is why non-atomic path was added to the macro. That path uses
> preempt_disable/enable so it can use local_clock().
>
> All this may, or may not be, compatible with PREEMPT_RT to start with?

Your assumption about atomic is not correct and that is why I aim to
ignore for RT. Or maybe alter so it fits.
It is assumed, that in_atomic() is true in an interrupts handler or with
an acquired spinlock_t, right? Both condition keep the context
preemptible so the atomic check triggers. However, both (the force
threaded interrupt handler and the spinlock_t) ensure that the task is
stuck on the CPU.

So maybe your _WAIT_FOR_ATOMIC_CHECK() could point to cant_migrate().
It looks like you try to ensure that local_clock() is from the same CPU.

> Or question phrased differently, how we should implement the <10us waits
> from non-atomic sections under PREEMPT_RT?

I think if you swap check in _WAIT_FOR_ATOMIC_CHECK() it should be good.
After all the remains preemptible during the condition polls so it
should work.

> > The problem is that you can't acquire that lock from within that
> > trace-point on PREEMPT_RT. On !RT it is possible but it is also
> > problematic because LOCKDEP does not see possible dead locks unless that
> > trace-point is enabled.
> 
> Oh I meant could the include ordering problem be fixed differently?
> 
> """
> [PATCH 07/10] drm/i915: skip DRM_I915_LOW_LEVEL_TRACEPOINTS with
>  NOTRACE
> 
> The order of the header files is important. If this header file is
> included after tracepoint.h was included then the NOTRACE here becomes a
> nop. Currently this happens for two .c files which use the tracepoitns
> behind DRM_I915_LOW_LEVEL_TRACEPOINTS.
> """
> 
> Like these two .c files - can order of includes just be changed in them?

Maybe. Let me check and get back to you.

> > I've been talking to Steven (after
> > https://lkml.kernel.org/r/20211214115837.6f33a...@gandalf.local.home)
> > and he wants to come up with something where you can pass a lock as
> > argument to the tracing-API. That way the lock can be acquired before
> > the trace event is invoked and lockdep will see it even if the trace
> > event is disabled.
> > So there is an idea how to get it to work eventually without disabling
> > it in the long term.
> > 
> > Making the register a raw_spinlock_t would solve problem immediately but
> > I am a little worried given the increased latency in a quick test:
> > 
> > https://lore.kernel.org/all/20211006164628.s2mtsdd2jdbfy...@linutronix.de/
> > 
> > also, this one single hardware but the upper limit atomic-polls is high.
> > 
> > > >  0008-drm-i915-gt-Queue-and-wait-for-the-irq_work-item.patch
> > > 
> > > Not sure about why cond_resched was put between irq_work_queue and
> > > irq_work_sync - would it not be like-for-like change to have the two
> > > together?
> > 
> > maybe it loops for a while and an additional scheduling would be nice.
> > 
> > > Commit message makes me think _queue already starts the handler on
> > > x86 at least.
> > 
> > Yes, irq_work_queue() triggers the IRQ right away on x86,
> > irq_work_sync() would wait for it to happen in case it did not happen.
> > On architectures which don't provide an IRQ-work interrupt, it is
> > delayed to the HZ tick timer interrupt. So this serves also as an
> > example in case someone want to copy the code ;)
> 
> My question wasn't why is there a need_resched() in there, but why is the
> patch:
> 
> + irq_work_queue(&b->irq_work);
>   cond_resched();
> + irq_work_sync(&b->irq_work);
> 
> And not:
> 
> + irq_work_queue(&b->irq_work);
> + irq_work_sync(&b->irq_work);
>   cond_resched();
> 
> To preserve like for like, if my understanding of the commit message was
> correct.

No strong need, it can be put as you suggest.
Should someone else schedule &b->irq_work from another CPU then you
could first attempt to cond_resched() and then wait for &b->irq_work's
completion. Assuming that this does not happen (because the irq_work was
previously queued and invoked immediately) irq_work_syn

[PATCH v2] drm/panfrost: cleanup comments

2022-03-02 Thread trix
From: Tom Rix 

For spdx
change tab to space delimiter
Use // for *.c

Replacements
commited to committed
regsiters to registers
initialze to initialize

Signed-off-by: Tom Rix 
---
v2: remove multiline comment change

 drivers/gpu/drm/panfrost/panfrost_drv.c  | 2 +-
 drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c | 2 +-
 drivers/gpu/drm/panfrost/panfrost_issues.h   | 2 +-
 drivers/gpu/drm/panfrost/panfrost_mmu.c  | 2 +-
 drivers/gpu/drm/panfrost/panfrost_regs.h | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 96bb5a4656278..94b6f0a19c83a 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -562,7 +562,7 @@ static int panfrost_probe(struct platform_device *pdev)
 
pfdev->coherent = device_get_dma_attr(&pdev->dev) == DEV_DMA_COHERENT;
 
-   /* Allocate and initialze the DRM device. */
+   /* Allocate and initialize the DRM device. */
ddev = drm_dev_alloc(&panfrost_drm_driver, &pdev->dev);
if (IS_ERR(ddev))
return PTR_ERR(ddev);
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c 
b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
index b0142341e2235..77e7cb6d1ae3b 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
 /* Copyright (C) 2019 Arm Ltd.
  *
  * Based on msm_gem_freedreno.c:
diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h 
b/drivers/gpu/drm/panfrost/panfrost_issues.h
index 8e59d765bf19f..501a76c5e95ff 100644
--- a/drivers/gpu/drm/panfrost/panfrost_issues.h
+++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
@@ -14,7 +14,7 @@
  */
 enum panfrost_hw_issue {
/* Need way to guarantee that all previously-translated memory accesses
-* are commited */
+* are committed */
HW_ISSUE_6367,
 
/* On job complete with non-done the cache is not flushed */
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index 39562f2d11a47..d3f82b26a631d 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier:GPL-2.0
+// SPDX-License-Identifier: GPL-2.0
 /* Copyright 2019 Linaro, Ltd, Rob Herring  */
 
 #include 
diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h 
b/drivers/gpu/drm/panfrost/panfrost_regs.h
index 6c5a11ef1ee87..efe4b75149d35 100644
--- a/drivers/gpu/drm/panfrost/panfrost_regs.h
+++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
@@ -292,7 +292,7 @@
 #define AS_FAULTADDRESS_LO(as) (MMU_AS(as) + 0x20) /* (RO) Fault 
Address for address space n, low word */
 #define AS_FAULTADDRESS_HI(as) (MMU_AS(as) + 0x24) /* (RO) Fault 
Address for address space n, high word */
 #define AS_STATUS(as)  (MMU_AS(as) + 0x28) /* (RO) Status 
flags for address space n */
-/* Additional Bifrost AS regsiters */
+/* Additional Bifrost AS registers */
 #define AS_TRANSCFG_LO(as) (MMU_AS(as) + 0x30) /* (RW) Translation 
table configuration for address space n, low word */
 #define AS_TRANSCFG_HI(as) (MMU_AS(as) + 0x34) /* (RW) Translation 
table configuration for address space n, high word */
 #define AS_FAULTEXTRA_LO(as)   (MMU_AS(as) + 0x38) /* (RO) Secondary 
fault address for address space n, low word */
-- 
2.26.3



Re: [PATCH v12 1/6] drm: Add arch arm64 for drm_clflush_virt_range

2022-03-02 Thread Robin Murphy

On 2022-02-25 19:27, Michael Cheng wrote:

Hi Robin,

[ +arm64 maintainers for their awareness, which would have been a good 
thing to do from the start ]


  * Thanks for adding the arm64 maintainer and sorry I didn't rope them
    in sooner.

Why does i915 need to ensure the CPU's instruction cache is coherent 
with its data cache? Is it a self-modifying driver?


  * Also thanks for pointing this out. Initially I was using
    dcache_clean_inval_poc, which seem to be the equivalently to what
    x86 is doing for dcache flushing, but it was giving me build errors
    since its not on the global list of kernel symbols. And after
    revisiting the documentation for caches_clean_inval_pou, it won't
    fly for what we are trying to do. Moving forward, what would you (or
    someone in the ARM community) suggest we do? Could it be possible to
    export dcache_clean_inval_poc as a global symbol?


Unlikely, unless something with a legitimate need for CPU-centric cache 
maintenance like kexec or CPU hotplug ever becomes modular.


In the case of a device driver, it's not even the basic issues of 
assuming to find direct equivalents to x86 semantics in other CPU 
architectures, or effectively reinventing parts of the DMA API, it's 
even bigger than that. Once you move from being integrated in a single 
vendor's system architecture to being on a discrete card, you 
fundamentally *no longer have any control over cache coherency*. Whether 
the host CPU architecture happens to be AArch64, RISC-V, or whatever 
doesn't really matter, you're at the mercy of 3rd-party PCIe and 
interconnect IP vendors, and SoC integrators. You'll find yourself in 
systems where PCIe simply cannot snoop any caches, where you'd better 
have the correct DMA API calls in place to have any hope of even the 
most basic functionality working properly; you'll find yourself in 
systems where even if the PCIe root complex claims to support No Snoop, 
your uncached traffic will still end up snooping stale data that got 
prefetched back into caches you thought you'd invalidated; you'll find 
yourself in systems where your memory attributes may or may not get 
forcibly rewritten by an IOMMU depending on the kernel config and/or 
command line.


It's not about simply finding a substitute for clflush, it's that the 
reasons you have for using clflush in the first place can no longer be 
assumed to be valid.


Robin.


On 2022-02-25 10:24 a.m., Robin Murphy wrote:
[ +arm64 maintainers for their awareness, which would have been a good 
thing to do from the start ]


On 2022-02-25 03:24, Michael Cheng wrote:

Add arm64 support for drm_clflush_virt_range. caches_clean_inval_pou
performs a flush by first performing a clean, follow by an invalidation
operation.

v2 (Michael Cheng): Use correct macro for cleaning and invalidation the
    dcache. Thanks Tvrtko for the suggestion.

v3 (Michael Cheng): Replace asm/cacheflush.h with linux/cacheflush.h

v4 (Michael Cheng): Arm64 does not export dcache_clean_inval_poc as a
    symbol that could be use by other modules, thus use
    caches_clean_inval_pou instead. Also this version
    removes include for cacheflush, since its already
    included base on architecture type.

Signed-off-by: Michael Cheng 
Reviewed-by: Matt Roper 
---
  drivers/gpu/drm/drm_cache.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index c3e6e615bf09..81c28714f930 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -174,6 +174,11 @@ drm_clflush_virt_range(void *addr, unsigned long 
length)

    if (wbinvd_on_all_cpus())
  pr_err("Timed out waiting for cache flush\n");
+
+#elif defined(CONFIG_ARM64)
+    void *end = addr + length;
+    caches_clean_inval_pou((unsigned long)addr, (unsigned long)end);


Why does i915 need to ensure the CPU's instruction cache is coherent 
with its data cache? Is it a self-modifying driver?


Robin.

(Note that the above is somewhat of a loaded question, and I do 
actually have half an idea of what you're trying to do here and why it 
won't fly, but I'd like to at least assume you've read the 
documentation of the function you decided was OK to use)



+
  #else
  WARN_ONCE(1, "Architecture has no drm_cache.c support\n");
  #endif


Re: [PATCH v2 2/4] drm/ttm: parameter to add extra pages into ttm_tt

2022-03-02 Thread Thomas Hellström
On Wed, 2022-03-02 at 03:23 +0530, Ramalingam C wrote:
> When a driver needs extra pages in ttm_tt, to facilidate such
> requirement, parameter called "extra_pages" is added for
> ttm_tt_init

nit: Please use imperative wording in commit title and description,
"Add a parameter to add extra pages.."

> 
> Signed-off-by: Ramalingam C 
> cc: Christian Koenig 
> cc: Hellstrom Thomas 

Otherwise LGTM.
Reviewed-by: Thomas Hellström 


> ---
>  drivers/gpu/drm/drm_gem_vram_helper.c  |  2 +-
>  drivers/gpu/drm/i915/gem/i915_gem_ttm.c    |  2 +-
>  drivers/gpu/drm/qxl/qxl_ttm.c  |  2 +-
>  drivers/gpu/drm/ttm/ttm_agp_backend.c  |  2 +-
>  drivers/gpu/drm/ttm/ttm_tt.c   | 12 +++-
>  drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c |  2 +-
>  include/drm/ttm/ttm_tt.h   |  4 +++-
>  7 files changed, 15 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c
> b/drivers/gpu/drm/drm_gem_vram_helper.c
> index dc7f938bfff2..123045b58fec 100644
> --- a/drivers/gpu/drm/drm_gem_vram_helper.c
> +++ b/drivers/gpu/drm/drm_gem_vram_helper.c
> @@ -867,7 +867,7 @@ static struct ttm_tt
> *bo_driver_ttm_tt_create(struct ttm_buffer_object *bo,
> if (!tt)
> return NULL;
>  
> -   ret = ttm_tt_init(tt, bo, page_flags, ttm_cached);
> +   ret = ttm_tt_init(tt, bo, page_flags, ttm_cached, 0);
> if (ret < 0)
> goto err_ttm_tt_init;
>  
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> index 45cc5837ce00..1a8262f5f692 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> @@ -283,7 +283,7 @@ static struct ttm_tt *i915_ttm_tt_create(struct
> ttm_buffer_object *bo,
> i915_tt->is_shmem = true;
> }
>  
> -   ret = ttm_tt_init(&i915_tt->ttm, bo, page_flags, caching);
> +   ret = ttm_tt_init(&i915_tt->ttm, bo, page_flags, caching, 0);
> if (ret)
> goto err_free;
>  
> diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c
> b/drivers/gpu/drm/qxl/qxl_ttm.c
> index b2e33d5ba5d0..52156b54498f 100644
> --- a/drivers/gpu/drm/qxl/qxl_ttm.c
> +++ b/drivers/gpu/drm/qxl/qxl_ttm.c
> @@ -113,7 +113,7 @@ static struct ttm_tt *qxl_ttm_tt_create(struct
> ttm_buffer_object *bo,
> ttm = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
> if (ttm == NULL)
> return NULL;
> -   if (ttm_tt_init(ttm, bo, page_flags, ttm_cached)) {
> +   if (ttm_tt_init(ttm, bo, page_flags, ttm_cached, 0)) {
> kfree(ttm);
> return NULL;
> }
> diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c
> b/drivers/gpu/drm/ttm/ttm_agp_backend.c
> index 6ddc16f0fe2b..d27691f2e451 100644
> --- a/drivers/gpu/drm/ttm/ttm_agp_backend.c
> +++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c
> @@ -134,7 +134,7 @@ struct ttm_tt *ttm_agp_tt_create(struct
> ttm_buffer_object *bo,
> agp_be->mem = NULL;
> agp_be->bridge = bridge;
>  
> -   if (ttm_tt_init(&agp_be->ttm, bo, page_flags,
> ttm_write_combined)) {
> +   if (ttm_tt_init(&agp_be->ttm, bo, page_flags,
> ttm_write_combined, 0)) {
> kfree(agp_be);
> return NULL;
> }
> diff --git a/drivers/gpu/drm/ttm/ttm_tt.c
> b/drivers/gpu/drm/ttm/ttm_tt.c
> index d234aab800a0..1a66d9fc589a 100644
> --- a/drivers/gpu/drm/ttm/ttm_tt.c
> +++ b/drivers/gpu/drm/ttm/ttm_tt.c
> @@ -134,9 +134,10 @@ void ttm_tt_destroy(struct ttm_device *bdev,
> struct ttm_tt *ttm)
>  static void ttm_tt_init_fields(struct ttm_tt *ttm,
>    struct ttm_buffer_object *bo,
>    uint32_t page_flags,
> -  enum ttm_caching caching)
> +  enum ttm_caching caching,
> +  unsigned long extra_pages)
>  {
> -   ttm->num_pages = PAGE_ALIGN(bo->base.size) >> PAGE_SHIFT;
> +   ttm->num_pages = (PAGE_ALIGN(bo->base.size) >> PAGE_SHIFT) +
> extra_pages;
> ttm->caching = ttm_cached;
> ttm->page_flags = page_flags;
> ttm->dma_address = NULL;
> @@ -146,9 +147,10 @@ static void ttm_tt_init_fields(struct ttm_tt
> *ttm,
>  }
>  
>  int ttm_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo,
> -   uint32_t page_flags, enum ttm_caching caching)
> +   uint32_t page_flags, enum ttm_caching caching,
> +   unsigned long extra_pages)
>  {
> -   ttm_tt_init_fields(ttm, bo, page_flags, caching);
> +   ttm_tt_init_fields(ttm, bo, page_flags, caching,
> extra_pages);
>  
> if (ttm_tt_alloc_page_directory(ttm)) {
> pr_err("Failed allocating page table\n");
> @@ -180,7 +182,7 @@ int ttm_sg_tt_init(struct ttm_tt *ttm, struct
> ttm_buffer_object *bo,
>  {
> int ret;
>  
> -   ttm_tt_init_fields(ttm, bo, page_flags, caching);
> +   ttm_tt_init_fields(ttm, bo, page_flag

Re: [PATCH v2 3/4] drm/i915/gem: Extra pages in ttm_tt for ccs data

2022-03-02 Thread Thomas Hellström
On Wed, 2022-03-02 at 03:23 +0530, Ramalingam C wrote:
> On Xe-HP and later devices, we use dedicated compression control
> state (CCS) stored in local memory for each surface, to support the
> 3D and media compression formats.
> 
> The memory required for the CCS of the entire local memory is 1/256
> of
> the local memory size. So before the kernel boot, the required memory
> is reserved for the CCS data and a secure register will be programmed
> with the CCS base address
> 
> So when we allocate a object in local memory we dont need to
> explicitly
> allocate the space for ccs data. But when we evict the obj into the
> smem to hold the compression related data along with the obj we need
> smem space of obj_size + (obj_size/256).
> 
> Hence when we create smem for an obj with lmem placement possibility
> we
> create with the extra space.

Nit: Again imperative wording, 


> 
> Signed-off-by: Ramalingam C 
> cc: Christian Koenig 
> cc: Hellstrom Thomas 

Reviewed by: Thomas Hellström 


> ---
>  drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 23 ++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> index 1a8262f5f692..c7a36861c38d 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> @@ -20,6 +20,7 @@
>  #include "gem/i915_gem_ttm.h"
>  #include "gem/i915_gem_ttm_move.h"
>  #include "gem/i915_gem_ttm_pm.h"
> +#include "gt/intel_gpu_commands.h"
>  
>  #define I915_TTM_PRIO_PURGE 0
>  #define I915_TTM_PRIO_NO_PAGES  1
> @@ -255,12 +256,27 @@ static const struct i915_refct_sgt_ops
> tt_rsgt_ops = {
> .release = i915_ttm_tt_release
>  };
>  
> +static inline bool
> +i915_gem_object_has_lmem_placement(struct drm_i915_gem_object *obj)
> +{
> +   int i;
> +
> +   for (i = 0; i < obj->mm.n_placements; i++)
> +   if (obj->mm.placements[i]->type ==
> INTEL_MEMORY_LOCAL)
> +   return true;
> +
> +   return false;
> +}
> +
>  static struct ttm_tt *i915_ttm_tt_create(struct ttm_buffer_object
> *bo,
>  uint32_t page_flags)
>  {
> +   struct drm_i915_private *i915 = container_of(bo->bdev,
> typeof(*i915),
> +    bdev);
> struct ttm_resource_manager *man =
> ttm_manager_type(bo->bdev, bo->resource->mem_type);
> struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
> +   unsigned long ccs_pages = 0;
> enum ttm_caching caching;
> struct i915_ttm_tt *i915_tt;
> int ret;
> @@ -283,7 +299,12 @@ static struct ttm_tt *i915_ttm_tt_create(struct
> ttm_buffer_object *bo,
> i915_tt->is_shmem = true;
> }
>  
> -   ret = ttm_tt_init(&i915_tt->ttm, bo, page_flags, caching, 0);
> +   if (HAS_FLAT_CCS(i915) &&
> i915_gem_object_has_lmem_placement(obj))
> +   ccs_pages = DIV_ROUND_UP(DIV_ROUND_UP(bo->base.size,
> +
> NUM_BYTES_PER_CCS_BYTE),
> +    PAGE_SIZE);
> +
> +   ret = ttm_tt_init(&i915_tt->ttm, bo, page_flags, caching,
> ccs_pages);
> if (ret)
> goto err_free;
>  




Re: [PATCH] drm/bridge: nwl-dsi: Remove superfluous write to NWL_DSI_IRQ_MASK register

2022-03-02 Thread Robert Foss
On Wed, 2 Mar 2022 at 12:35, Guido Günther  wrote:
>
> Hi Liu,
> On Wed, Feb 16, 2022 at 04:58:42PM +0800, Liu Ying wrote:
> > To initialize register NWL_DSI_IRQ_MASK, it's enough to write it
> > only once in function nwl_dsi_init_interrupts().
> >
> > Signed-off-by: Liu Ying 
> > ---
> >  drivers/gpu/drm/bridge/nwl-dsi.c | 14 +-
> >  1 file changed, 5 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c 
> > b/drivers/gpu/drm/bridge/nwl-dsi.c
> > index af07eeb47ca0..fcc4a2889ad4 100644
> > --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> > +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> > @@ -333,17 +333,13 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
> >
> >  static int nwl_dsi_init_interrupts(struct nwl_dsi *dsi)
> >  {
> > - u32 irq_enable;
> > -
> > - nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, 0x);
> > - nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7);
> > -
> > - irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK |
> > - NWL_DSI_RX_PKT_HDR_RCVD_MASK |
> > - NWL_DSI_TX_FIFO_OVFLW_MASK |
> > - NWL_DSI_HS_TX_TIMEOUT_MASK);
> > + u32 irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK |
> > + NWL_DSI_RX_PKT_HDR_RCVD_MASK |
> > + NWL_DSI_TX_FIFO_OVFLW_MASK |
> > + NWL_DSI_HS_TX_TIMEOUT_MASK);
> >
> >   nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, irq_enable);
> > + nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7);
>
> Works fine here. I thought it was due to some hw quirk but can't find
> any note in it so:
>
> Reviewed-by: Guido Günther 
>
> Thanks,
>  -- Guido

Applied to drm-misc-next


Re: [PATCH v2 2/4] drm/ttm: parameter to add extra pages into ttm_tt

2022-03-02 Thread Christian König

Am 01.03.22 um 22:53 schrieb Ramalingam C:

When a driver needs extra pages in ttm_tt, to facilidate such
requirement, parameter called "extra_pages" is added for
ttm_tt_init

Signed-off-by: Ramalingam C 
cc: Christian Koenig 
cc: Hellstrom Thomas 


With the nits pointed out by Thomas the patch is Reviewed-by: Christian 
König  as well.


Let me know through which branch you want to push this upstream (i915 or 
drm-misc-next).


Thanks,
Christian.


---
  drivers/gpu/drm/drm_gem_vram_helper.c  |  2 +-
  drivers/gpu/drm/i915/gem/i915_gem_ttm.c|  2 +-
  drivers/gpu/drm/qxl/qxl_ttm.c  |  2 +-
  drivers/gpu/drm/ttm/ttm_agp_backend.c  |  2 +-
  drivers/gpu/drm/ttm/ttm_tt.c   | 12 +++-
  drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c |  2 +-
  include/drm/ttm/ttm_tt.h   |  4 +++-
  7 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
b/drivers/gpu/drm/drm_gem_vram_helper.c
index dc7f938bfff2..123045b58fec 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -867,7 +867,7 @@ static struct ttm_tt *bo_driver_ttm_tt_create(struct 
ttm_buffer_object *bo,
if (!tt)
return NULL;
  
-	ret = ttm_tt_init(tt, bo, page_flags, ttm_cached);

+   ret = ttm_tt_init(tt, bo, page_flags, ttm_cached, 0);
if (ret < 0)
goto err_ttm_tt_init;
  
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c

index 45cc5837ce00..1a8262f5f692 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -283,7 +283,7 @@ static struct ttm_tt *i915_ttm_tt_create(struct 
ttm_buffer_object *bo,
i915_tt->is_shmem = true;
}
  
-	ret = ttm_tt_init(&i915_tt->ttm, bo, page_flags, caching);

+   ret = ttm_tt_init(&i915_tt->ttm, bo, page_flags, caching, 0);
if (ret)
goto err_free;
  
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c

index b2e33d5ba5d0..52156b54498f 100644
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
@@ -113,7 +113,7 @@ static struct ttm_tt *qxl_ttm_tt_create(struct 
ttm_buffer_object *bo,
ttm = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
if (ttm == NULL)
return NULL;
-   if (ttm_tt_init(ttm, bo, page_flags, ttm_cached)) {
+   if (ttm_tt_init(ttm, bo, page_flags, ttm_cached, 0)) {
kfree(ttm);
return NULL;
}
diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c 
b/drivers/gpu/drm/ttm/ttm_agp_backend.c
index 6ddc16f0fe2b..d27691f2e451 100644
--- a/drivers/gpu/drm/ttm/ttm_agp_backend.c
+++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c
@@ -134,7 +134,7 @@ struct ttm_tt *ttm_agp_tt_create(struct ttm_buffer_object 
*bo,
agp_be->mem = NULL;
agp_be->bridge = bridge;
  
-	if (ttm_tt_init(&agp_be->ttm, bo, page_flags, ttm_write_combined)) {

+   if (ttm_tt_init(&agp_be->ttm, bo, page_flags, ttm_write_combined, 0)) {
kfree(agp_be);
return NULL;
}
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index d234aab800a0..1a66d9fc589a 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -134,9 +134,10 @@ void ttm_tt_destroy(struct ttm_device *bdev, struct ttm_tt 
*ttm)
  static void ttm_tt_init_fields(struct ttm_tt *ttm,
   struct ttm_buffer_object *bo,
   uint32_t page_flags,
-  enum ttm_caching caching)
+  enum ttm_caching caching,
+  unsigned long extra_pages)
  {
-   ttm->num_pages = PAGE_ALIGN(bo->base.size) >> PAGE_SHIFT;
+   ttm->num_pages = (PAGE_ALIGN(bo->base.size) >> PAGE_SHIFT) + 
extra_pages;
ttm->caching = ttm_cached;
ttm->page_flags = page_flags;
ttm->dma_address = NULL;
@@ -146,9 +147,10 @@ static void ttm_tt_init_fields(struct ttm_tt *ttm,
  }
  
  int ttm_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo,

-   uint32_t page_flags, enum ttm_caching caching)
+   uint32_t page_flags, enum ttm_caching caching,
+   unsigned long extra_pages)
  {
-   ttm_tt_init_fields(ttm, bo, page_flags, caching);
+   ttm_tt_init_fields(ttm, bo, page_flags, caching, extra_pages);
  
  	if (ttm_tt_alloc_page_directory(ttm)) {

pr_err("Failed allocating page table\n");
@@ -180,7 +182,7 @@ int ttm_sg_tt_init(struct ttm_tt *ttm, struct 
ttm_buffer_object *bo,
  {
int ret;
  
-	ttm_tt_init_fields(ttm, bo, page_flags, caching);

+   ttm_tt_init_fields(ttm, bo, page_flags, caching, 0);
  
  	if (page_flags & TTM_TT_FLAG_EXTERNAL)

ret = ttm_sg_tt_alloc_page_directory(ttm);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c 
b/drivers/gpu/drm

Re: [PATCH v2] drm/panfrost: cleanup comments

2022-03-02 Thread Steven Price
On 02/03/2022 12:45, t...@redhat.com wrote:
> From: Tom Rix 
> 
> For spdx
> change tab to space delimiter
> Use // for *.c
> 
> Replacements
> commited to committed
> regsiters to registers
> initialze to initialize
> 
> Signed-off-by: Tom Rix 

Reviewed-by: Steven Price 

> ---
> v2: remove multiline comment change

Thanks for the update. I'll push this to drm-misc-next.

Steve

> 
>  drivers/gpu/drm/panfrost/panfrost_drv.c  | 2 +-
>  drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c | 2 +-
>  drivers/gpu/drm/panfrost/panfrost_issues.h   | 2 +-
>  drivers/gpu/drm/panfrost/panfrost_mmu.c  | 2 +-
>  drivers/gpu/drm/panfrost/panfrost_regs.h | 2 +-
>  5 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
> b/drivers/gpu/drm/panfrost/panfrost_drv.c
> index 96bb5a4656278..94b6f0a19c83a 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> @@ -562,7 +562,7 @@ static int panfrost_probe(struct platform_device *pdev)
>  
>   pfdev->coherent = device_get_dma_attr(&pdev->dev) == DEV_DMA_COHERENT;
>  
> - /* Allocate and initialze the DRM device. */
> + /* Allocate and initialize the DRM device. */
>   ddev = drm_dev_alloc(&panfrost_drm_driver, &pdev->dev);
>   if (IS_ERR(ddev))
>   return PTR_ERR(ddev);
> diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c 
> b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
> index b0142341e2235..77e7cb6d1ae3b 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
> @@ -1,4 +1,4 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> +// SPDX-License-Identifier: GPL-2.0
>  /* Copyright (C) 2019 Arm Ltd.
>   *
>   * Based on msm_gem_freedreno.c:
> diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h 
> b/drivers/gpu/drm/panfrost/panfrost_issues.h
> index 8e59d765bf19f..501a76c5e95ff 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_issues.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
> @@ -14,7 +14,7 @@
>   */
>  enum panfrost_hw_issue {
>   /* Need way to guarantee that all previously-translated memory accesses
> -  * are commited */
> +  * are committed */
>   HW_ISSUE_6367,
>  
>   /* On job complete with non-done the cache is not flushed */
> diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
> b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> index 39562f2d11a47..d3f82b26a631d 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> @@ -1,4 +1,4 @@
> -// SPDX-License-Identifier:  GPL-2.0
> +// SPDX-License-Identifier: GPL-2.0
>  /* Copyright 2019 Linaro, Ltd, Rob Herring  */
>  
>  #include 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h 
> b/drivers/gpu/drm/panfrost/panfrost_regs.h
> index 6c5a11ef1ee87..efe4b75149d35 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_regs.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
> @@ -292,7 +292,7 @@
>  #define AS_FAULTADDRESS_LO(as)   (MMU_AS(as) + 0x20) /* (RO) 
> Fault Address for address space n, low word */
>  #define AS_FAULTADDRESS_HI(as)   (MMU_AS(as) + 0x24) /* (RO) 
> Fault Address for address space n, high word */
>  #define AS_STATUS(as)(MMU_AS(as) + 0x28) /* (RO) 
> Status flags for address space n */
> -/* Additional Bifrost AS regsiters */
> +/* Additional Bifrost AS registers */
>  #define AS_TRANSCFG_LO(as)   (MMU_AS(as) + 0x30) /* (RW) Translation 
> table configuration for address space n, low word */
>  #define AS_TRANSCFG_HI(as)   (MMU_AS(as) + 0x34) /* (RW) Translation 
> table configuration for address space n, high word */
>  #define AS_FAULTEXTRA_LO(as) (MMU_AS(as) + 0x38) /* (RO) Secondary 
> fault address for address space n, low word */



Re: [PATCH 1/2] drm: Introduce DRM_BRIDGE_OP_UPSTREAM_FIRST to alter bridge init order

2022-03-02 Thread Dave Stevenson
Hi Andrzej

On Mon, 28 Feb 2022 at 15:36, Andrzej Hajda  wrote:
>
>
>
> On 22.02.2022 09:43, Dave Stevenson wrote:
> > Hi Laurent.
> >
> > Thanks for the review.
> >
> > On Tue, 22 Feb 2022 at 06:34, Laurent Pinchart
> >  wrote:
> >> Hi Dave,
> >>
> >> Thank you for the patch.
> >>
> >> On Wed, Feb 16, 2022 at 04:59:43PM +, Dave Stevenson wrote:
> >>> DSI sink devices typically want the DSI host powered up and configured
> >>> before they are powered up. pre_enable is the place this would normally
> >>> happen, but they are called in reverse order from panel/connector towards
> >>> the encoder, which is the "wrong" order.
> >>>
> >>> Add a new flag DRM_BRIDGE_OP_UPSTREAM_FIRST that any bridge can set
> >>> to swap the order of pre_enable (and post_disable) so that any upstream
> >>> bridges are called first to create the desired state.
> >>>
> >>> eg:
> >>> - Panel
> >>> - Bridge 1
> >>> - Bridge 2 DRM_BRIDGE_OP_UPSTREAM_FIRST
> >>> - Bridge 3
> >>> - Encoder
> >>> Would result in pre_enable's being called as Panel, Bridge 1, Bridge 3,
> >>> Bridge 2.
> >> If there was a Bridge 4 between Bridge 3 and Encoder, would it be
> >>
> >> Panel, Bridge 1, Bridge 3, Bridge 4, Bridge 2
> >>
> >> ? I'd capture that here, to be explicit.
> > No.
> >   - Panel
> >   - Bridge 1
> >   - Bridge 2 DRM_BRIDGE_OP_UPSTREAM_FIRST
> >   - Bridge 3
> >   - Bridge 4
> >- Encoder
> > Would result in pre_enable's being called as Panel, Bridge 1, Bridge
> > 3, Bridge 2, Bridge 4, Encoder.
> > ie it only swaps the order of bridges 2 & 3.
> >
> >   - Panel
> >   - Bridge 1
> >   - Bridge 2 DRM_BRIDGE_OP_UPSTREAM_FIRST
> >   - Bridge 3 DRM_BRIDGE_OP_UPSTREAM_FIRST
> >   - Bridge 4
> >   - Encoder
> > Would result in pre_enable's being called as Panel, Bridge 1, Bridge
> > 4, Bridge 3, Bridge 2, Encoder.
> > (Bridge 2&3 have asked for upstream to be enabled first, which means
> > bridge 4. Bridge 2 wants upstream enabled first, which means bridge
> > 3).
> >
> >   - Panel
> >   - Bridge 1
> >   - Bridge 2 DRM_BRIDGE_OP_UPSTREAM_FIRST
> >   - Bridge 3
> >   - Bridge 4 DRM_BRIDGE_OP_UPSTREAM_FIRST
> >   - Bridge 5
> >   - Encoder
> > Would result in Panel, Bridge 1, Bridge 3, Bridge 2, Bridge 5, Bridge
> > 4, Encoder.
> >
> > So we only reverse the order whilst the bridges request that they want
> > upstream enabled first, but we can do that multiple times within the
> > chain. I hope that makes sense.
> >
> >>> Signed-off-by: Dave Stevenson 
> >>> ---
> >>>   drivers/gpu/drm/drm_bridge.c | 197 
> >>> +--
> >>>   include/drm/drm_bridge.h |   8 ++
> >>>   2 files changed, 180 insertions(+), 25 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> >>> index c96847fc0ebc..7c24e8340efa 100644
> >>> --- a/drivers/gpu/drm/drm_bridge.c
> >>> +++ b/drivers/gpu/drm/drm_bridge.c
> >>> @@ -522,21 +522,58 @@ EXPORT_SYMBOL(drm_bridge_chain_disable);
> >>>* Calls &drm_bridge_funcs.post_disable op for all the bridges in the
> >>>* encoder chain, starting from the first bridge to the last. These are 
> >>> called
> >>>* after completing the encoder's prepare op.
> >> Missing blank line, as well as in three locations below.
> >>
> >>> + * If a bridge sets the DRM_BRIDGE_OP_UPSTREAM_FIRST, then the 
> >>> post_disable for
> >>> + * that bridge will be called before the previous one to reverse the 
> >>> pre_enable
> >>> + * calling direction.
> >>>*
> >>>* Note: the bridge passed should be the one closest to the encoder
> >>>*/
> >>>   void drm_bridge_chain_post_disable(struct drm_bridge *bridge)
> >>>   {
> >>>struct drm_encoder *encoder;
> >>> + struct drm_bridge *next, *limit;
> >>>
> >>>if (!bridge)
> >>>return;
> >>>
> >>>encoder = bridge->encoder;
> >>>list_for_each_entry_from(bridge, &encoder->bridge_chain, 
> >>> chain_node) {
> >>> + limit = NULL;
> >>> +
> >>> + if (!list_is_last(&bridge->chain_node, 
> >>> &encoder->bridge_chain)) {
> >>> + next = list_next_entry(bridge, chain_node);
> >>> +
> >>> + if (next->ops & DRM_BRIDGE_OP_UPSTREAM_FIRST) {
> >>> + limit = next;
> >>> +
> >>> + list_for_each_entry_from(next, 
> >>> &encoder->bridge_chain,
> >>> +  chain_node) {
> >>> + if (!(next->ops &
> >>> + 
> >>> DRM_BRIDGE_OP_UPSTREAM_FIRST)) {
> >>> + next = 
> >>> list_prev_entry(next, chain_node);
> >>> + limit = next;
> >>> + break;
> >>> + }
> >>> + }
> >>> +
> >>> + list_for_each_entry_from_reverse(next, 
>

RE: [PATCH 2/6] treewide: remove using list iterator after loop body as a ptr

2022-03-02 Thread David Laight
From: Xiaomeng Tong
> Sent: 02 March 2022 09:31
> 
> On Mon, 28 Feb 2022 16:41:04 -0800, Linus Torvalds
>  wrote:
> >
> > But basically to _me_, the important part is that the end result is
> > maintainable longer-term.
> 
> I couldn't agree more. And because of that, I stick with the following
> approach because it's maintainable longer-term than "type(pos) pos" one:
>  Implements a new macro for each list_for_each_entry* with _inside suffix.
>   #define list_for_each_entry_inside(pos, type, head, member)

I think that it would be better to make any alternate loop macro
just set the variable to NULL on the loop exit.
That is easier to code for and the compiler might be persuaded to
not redo the test.

It also doesn't need an extra variable defined in the for() statement
so can be back-ported to older kernels without required declaration
in the middle of blocks.

OTOH there may be alternative definitions that can be used to get
the compiler (or other compiler-like tools) to detect broken code.
Even if the definition can't possibly generate a working kerrnel.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



[Bug 215648] amdgpu: Changing monitor configuration (plug/unplug/wake from DPMS) causes kernel panic

2022-03-02 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215648

--- Comment #3 from Alex Deucher (alexdeuc...@gmail.com) ---
Thanks.  Can you get the dmesg output from boot prior to the hang?

-- 
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 215648] amdgpu: Changing monitor configuration (plug/unplug/wake from DPMS) causes kernel panic

2022-03-02 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215648

--- Comment #4 from Philipp Riederer (pr_ker...@tum.fail) ---
Created attachment 300517
  --> https://bugzilla.kernel.org/attachment.cgi?id=300517&action=edit
dmesg from boot using kernel 5.15.12@94ba5b0fb52d6dbf1f200351876a839afb74aedd

-- 
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 215648] amdgpu: Changing monitor configuration (plug/unplug/wake from DPMS) causes kernel panic

2022-03-02 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215648

--- Comment #5 from Philipp Riederer (pr_ker...@tum.fail) ---
Hey,

Thank you for working on this!

I added the dmesg as attachment to the bug. Please note that this is from the
working kernel (commit 94ba5b0fb52d6dbf1f200351876a839afb74aedd) as that is the
one I have running now. If it helps, I can also provide the messages from a
non-working kernel later.

Cheers,
Philipp

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

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

Re: [RFC PATCH] drm/panel: simple: panel-dpi: use bus-format to set bpc and bus_format

2022-03-02 Thread Maxime Ripard
Hi,

Please try to avoid top posting

On Wed, Feb 23, 2022 at 04:25:19PM +0100, Max Krummenacher wrote:
> The goal here is to set the element bus_format in the struct
> panel_desc. This is an enum with the possible values defined in
> include/uapi/linux/media-bus-format.h.
> 
> The enum values are not constructed in a way that you could calculate
> the value from color channel width/shift/mapping/whatever. You rather
> would have to check if the combination of color channel
> width/shift/mapping/whatever maps to an existing value and otherwise
> EINVAL out.
> 
> I don't see the value in having yet another way of how this
> information can be specified and then having to write a more
> complicated parser which maps the dt data to bus_format.

Generally speaking, sending an RFC without explicitly stating what you
want a comment on isn't very efficient.

That being said, what I (and I can only assume Marek) don't like is the
string encoding. Especially when the similar bus-type property uses a
integer with the various available bus options we have.

Having an integer, with a set of defines that you would map to the
proper MEDIA_BUS_* would be more efficient and more elegant.

That being said, the first question that needs to be answered is why
does this have to be in the DT in the first place?

Maxime


signature.asc
Description: PGP signature


[PATCH] video: fbdev: sm712fb: Fix crash in smtcfb_write()

2022-03-02 Thread Zheyu Ma
When the sm712fb driver writes three bytes to the framebuffer, the
driver will crash:

BUG: unable to handle page fault for address: c90001ff
RIP: 0010:smtcfb_write+0x454/0x5b0
Call Trace:
 vfs_write+0x291/0xd60
 ? do_sys_openat2+0x27d/0x350
 ? __fget_light+0x54/0x340
 ksys_write+0xce/0x190
 do_syscall_64+0x43/0x90
 entry_SYSCALL_64_after_hwframe+0x44/0xae

Fix it by removing the open-coded endianness fixup-code.

Signed-off-by: Zheyu Ma 
---
 drivers/video/fbdev/sm712fb.c | 21 -
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index 0dbc6bf8268a..e355089ac7d6 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1130,7 +1130,7 @@ static ssize_t smtcfb_write(struct fb_info *info, const 
char __user *buf,
count = total_size - p;
}
 
-   buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
+   buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
 
@@ -1148,24 +1148,11 @@ static ssize_t smtcfb_write(struct fb_info *info, const 
char __user *buf,
break;
}
 
-   for (i = c >> 2; i--;) {
-   fb_writel(big_swap(*src), dst++);
+   for (i = (c + 3) >> 2; i--;) {
+   fb_writel(big_swap(*src), dst);
+   dst++;
src++;
}
-   if (c & 3) {
-   u8 *src8 = (u8 *)src;
-   u8 __iomem *dst8 = (u8 __iomem *)dst;
-
-   for (i = c & 3; i--;) {
-   if (i & 1) {
-   fb_writeb(*src8++, ++dst8);
-   } else {
-   fb_writeb(*src8++, --dst8);
-   dst8 += 2;
-   }
-   }
-   dst = (u32 __iomem *)dst8;
-   }
 
*ppos += c;
buf += c;
-- 
2.25.1



Re: [PATCH v16 4/4] drm/bridge: dw-hdmi: fix bus formats negotiation for 8 bit modes

2022-03-02 Thread Neil Armstrong

Hi,

On 02/03/2022 12:15, H. Nikolaus Schaller wrote:

Hi Neil,


Am 02.03.2022 um 11:25 schrieb Neil Armstrong :


I added a printk for hdmi->sink_is_hdmi. This returns 1. Which IMHO is to be 
expected
since I am using a HDMI connector and panel... So your patch will still add the 
UYVY formats.
Either the synposys module inside the jz4780 or the panel does not understand 
them.


By selecting the UYVY formats, the driver will enable the colorspace converters 
in the dw-hdmi IP,
I don't see why it doesn't work here...

There is a bit called `Support Color Space Converter` in config0_id:
bit |   Name|   R/W |   Desc
2   |   csc |   R   |   Indicates if Color Space 
Conversion block is present

Could you dump all the config0 bits:

===><=
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 54d8fdad395f..547731482da8 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -3431,6 +3431,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device 
*pdev,
pdevinfo.id = PLATFORM_DEVID_AUTO;

config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID);
+   dev_info(dev, "config0: %x\n", config0);
config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);

if (iores && config3 & HDMI_CONFIG3_AHBAUDDMA) {
===><=

If this bit is missing, this would explain the black screen.


[9.291011] dw-hdmi-ingenic 1018.hdmi: config0: bf

Hm. Or is the color-space conversion of the sw-hdmi module inside the jz4780 
broken
or not configured properly?

(cross-checked: RGB mode still works if I force hdmi->sink_is_hdmi = false)


I don't understand what's wrong, can you try to make the logic select 
MEDIA_BUS_FMT_YUV8_1X24 instead of DRM_COLOR_FORMAT_YCBCR422 ?

If your CSC is broken, we'll need to disable it on your platform.

Thanks,
Neil



BR and thanks,
Nikolaus





Re: [PATCH V2 03/12] drm: bridge: icn6211: Add HS/VS/DE polarity handling

2022-03-02 Thread Marek Vasut

On 3/2/22 10:59, Maxime Ripard wrote:

On Thu, Feb 17, 2022 at 01:25:21AM +0100, Marek Vasut wrote:

The driver currently hard-codes HS/VS polarity to active-low and DE to
active-high, which is not correct for a lot of supported DPI panels.
Add the missing mode flag handling for HS/VS/DE polarity.

Signed-off-by: Marek Vasut 
Cc: Jagan Teki 
Cc: Maxime Ripard 
Cc: Robert Foss 
Cc: Sam Ravnborg 
Cc: Thomas Zimmermann 
To: dri-devel@lists.freedesktop.org
---
V2: Rebase on next-20220214
---
  drivers/gpu/drm/bridge/chipone-icn6211.c | 16 +++-
  1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c 
b/drivers/gpu/drm/bridge/chipone-icn6211.c
index e29e6a84c39a6..2ac8eb7e25f52 100644
--- a/drivers/gpu/drm/bridge/chipone-icn6211.c
+++ b/drivers/gpu/drm/bridge/chipone-icn6211.c
@@ -165,8 +165,16 @@ static void chipone_atomic_enable(struct drm_bridge 
*bridge,
  struct drm_bridge_state *old_bridge_state)
  {
struct chipone *icn = bridge_to_chipone(bridge);
+   struct drm_atomic_state *state = old_bridge_state->base.state;
struct drm_display_mode *mode = &icn->mode;
+   const struct drm_bridge_state *bridge_state;
u16 hfp, hbp, hsync;
+   u32 bus_flags;
+   u8 pol;
+
+   /* Get the DPI flags from the bridge state. */
+   bridge_state = drm_atomic_get_new_bridge_state(state, bridge);
+   bus_flags = bridge_state->output_bus_cfg.flags;
  
  	ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_DSI);
  
@@ -206,7 +214,13 @@ static void chipone_atomic_enable(struct drm_bridge *bridge,

ICN6211_DSI(icn, HFP_MIN, hfp & 0xff);
ICN6211_DSI(icn, MIPI_PD_CK_LANE, 0xa0);
ICN6211_DSI(icn, PLL_CTRL(12), 0xff);
-   ICN6211_DSI(icn, BIST_POL, BIST_POL_DE_POL);
+
+   /* DPI HS/VS/DE polarity */
+   pol = ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? BIST_POL_HSYNC_POL : 0) |
+ ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? BIST_POL_VSYNC_POL : 0) |
+ ((bus_flags & DRM_BUS_FLAG_DE_HIGH) ? BIST_POL_DE_POL : 0);


Is there a reason you didn't use bus_flags for all the polarities there?


Because there is no separate HS/VS bus flag, that's why HS/VS is pulled 
from mode flags.


Re: [PATCH V2 04/12] drm: bridge: icn6211: Add DSI lane count DT property parsing

2022-03-02 Thread Marek Vasut

On 3/2/22 11:01, Maxime Ripard wrote:

On Thu, Feb 17, 2022 at 01:25:22AM +0100, Marek Vasut wrote:

The driver currently hard-codes DSI lane count to two, however the chip
is capable of operating in 1..4 DSI lanes mode. Parse 'data-lanes' DT
property and program the result into DSI_CTRL register.

Signed-off-by: Marek Vasut 
Cc: Jagan Teki 
Cc: Maxime Ripard 
Cc: Robert Foss 
Cc: Sam Ravnborg 
Cc: Thomas Zimmermann 
To: dri-devel@lists.freedesktop.org
---
V2: Rebase on next-20220214
---
  drivers/gpu/drm/bridge/chipone-icn6211.c | 21 -
  1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c 
b/drivers/gpu/drm/bridge/chipone-icn6211.c
index 2ac8eb7e25f52..7c013a08c7b00 100644
--- a/drivers/gpu/drm/bridge/chipone-icn6211.c
+++ b/drivers/gpu/drm/bridge/chipone-icn6211.c
@@ -136,10 +136,12 @@ struct chipone {
struct drm_bridge bridge;
struct drm_display_mode mode;
struct drm_bridge *panel_bridge;
+   struct device_node *host_node;
struct gpio_desc *enable_gpio;
struct regulator *vdd1;
struct regulator *vdd2;
struct regulator *vdd3;
+   int dsi_lanes;
  };
  
  static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge)

@@ -212,6 +214,11 @@ static void chipone_atomic_enable(struct drm_bridge 
*bridge,
/* dsi specific sequence */
ICN6211_DSI(icn, SYNC_EVENT_DLY, 0x80);
ICN6211_DSI(icn, HFP_MIN, hfp & 0xff);
+
+   /* DSI data lane count */
+   ICN6211_DSI(icn, DSI_CTRL,
+   DSI_CTRL_UNKNOWN | DSI_CTRL_DSI_LANES(icn->dsi_lanes - 1));
+
ICN6211_DSI(icn, MIPI_PD_CK_LANE, 0xa0);
ICN6211_DSI(icn, PLL_CTRL(12), 0xff);
  
@@ -314,6 +321,7 @@ static const struct drm_bridge_funcs chipone_bridge_funcs = {

  static int chipone_parse_dt(struct chipone *icn)
  {
struct device *dev = icn->dev;
+   struct device_node *endpoint;
struct drm_panel *panel;
int ret;
  
@@ -350,6 +358,16 @@ static int chipone_parse_dt(struct chipone *icn)

return PTR_ERR(icn->enable_gpio);
}
  
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);

+   icn->dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes");


The binding must be amended to allow for the usage of data-lanes, and
you need to keep the previous value as default for older device trees


Regarding the default value -- there are no in-tree users of this driver 
yet (per git grep in current linux-next), do we really care about 
backward compatibility in this case?


[PATCH 0/8] drm/vmwgfx: 3D on arm64 and large cursor support

2022-03-02 Thread Zack Rusin
From: Zack Rusin 

Series finishes 3D support on arm64 with vmwgfx. With this and changes
that add svga3 pci id's to Mesa3D - OpenGL 4.3 and GLES 3.1 work smoothly
on arm64.
   
Most changes are not svga3 specific but rather could be classified as
generic improvements. That's in particular true for support for curso
mobs which enable large cursor support on both svga2 and svga3 and fixing
initialization of drm_mode_fb_cmd2 struct.

Martin Krastev (1):
  drm/vmwgfx: Add support for CursorMob and CursorBypass 4

Zack Rusin (7):
  drm/vmwgfx: Cleanup multimon initialization code
  drm/vmwgfx: Print capabilities early during the initialization
  drm/vmwgfx: Fix fencing on SVGAv3
  drm/vmwgfx: Allow querying of the SVGA PCI id from the userspace
  drm/vmwgfx: Initialize drm_mode_fb_cmd2
  drm/vmwgfx: Implement MSI/MSI-X support for IRQs
  drm/vmwgfx: Stop using surface dma commands on most configurations

 drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c   |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   |  20 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h   |  23 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_fb.c|   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |  28 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c |  27 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_irq.c   |  80 -
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   | 407 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h   |  28 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c   |  36 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c  |  17 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c  |  27 +-
 include/uapi/drm/vmwgfx_drm.h |   9 +-
 13 files changed, 538 insertions(+), 168 deletions(-)

-- 
2.32.0



[PATCH 3/8] drm/vmwgfx: Print capabilities early during the initialization

2022-03-02 Thread Zack Rusin
From: Zack Rusin 

Capabilities were logged at the end of initialization so any early errors
would make them not appear in the logs. Which is also when they're needed
the most.
Print the the capabilities right after fetching them, before the init
code starts using them to make sure they always show up in the logs.

Signed-off-by: Zack Rusin 
Reviewed-by: Martin Krastev 
Reviewed-by: Maaz Mombasawala 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 621231c66fd4..f43afd56915e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -848,12 +848,16 @@ static int vmw_driver_load(struct vmw_private *dev_priv, 
u32 pci_id)
 
 
dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES);
-
+   vmw_print_bitmap(&dev_priv->drm, "Capabilities",
+dev_priv->capabilities,
+cap1_names, ARRAY_SIZE(cap1_names));
if (dev_priv->capabilities & SVGA_CAP_CAP2_REGISTER) {
dev_priv->capabilities2 = vmw_read(dev_priv, SVGA_REG_CAP2);
+   vmw_print_bitmap(&dev_priv->drm, "Capabilities2",
+dev_priv->capabilities2,
+cap2_names, ARRAY_SIZE(cap2_names));
}
 
-
ret = vmw_dma_select_mode(dev_priv);
if (unlikely(ret != 0)) {
drm_info(&dev_priv->drm,
@@ -939,14 +943,6 @@ static int vmw_driver_load(struct vmw_private *dev_priv, 
u32 pci_id)
 "MOB limits: max mob size = %u kB, max mob pages = %u\n",
 dev_priv->max_mob_size / 1024, dev_priv->max_mob_pages);
 
-   vmw_print_bitmap(&dev_priv->drm, "Capabilities",
-dev_priv->capabilities,
-cap1_names, ARRAY_SIZE(cap1_names));
-   if (dev_priv->capabilities & SVGA_CAP_CAP2_REGISTER)
-   vmw_print_bitmap(&dev_priv->drm, "Capabilities2",
-dev_priv->capabilities2,
-cap2_names, ARRAY_SIZE(cap2_names));
-
ret = vmw_dma_masks(dev_priv);
if (unlikely(ret != 0))
goto out_err0;
-- 
2.32.0



[PATCH 2/8] drm/vmwgfx: Cleanup multimon initialization code

2022-03-02 Thread Zack Rusin
From: Zack Rusin 

The results of the legacy display unit initialization were being silently
ignored. Unifying the selection of number of display units based
on whether the underlying device supports multimon makes it easier
to add error checking to all paths.

This makes the driver report the errors in ldu initialization paths
and try to recover from them.

Signed-off-by: Zack Rusin 
Reviewed-by: Martin Krastev 
Reviewed-by: Maaz Mombasawala 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index 643c1608ddfd..e4347faccee0 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -492,6 +492,8 @@ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv)
 {
struct drm_device *dev = &dev_priv->drm;
int i, ret;
+   int num_display_units = (dev_priv->capabilities & SVGA_CAP_MULTIMON) ?
+   VMWGFX_NUM_DISPLAY_UNITS : 1;
 
if (unlikely(dev_priv->ldu_priv)) {
return -EINVAL;
@@ -506,21 +508,17 @@ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv)
dev_priv->ldu_priv->last_num_active = 0;
dev_priv->ldu_priv->fb = NULL;
 
-   /* for old hardware without multimon only enable one display */
-   if (dev_priv->capabilities & SVGA_CAP_MULTIMON)
-   ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS);
-   else
-   ret = drm_vblank_init(dev, 1);
+   ret = drm_vblank_init(dev, num_display_units);
if (ret != 0)
goto err_free;
 
vmw_kms_create_implicit_placement_property(dev_priv);
 
-   if (dev_priv->capabilities & SVGA_CAP_MULTIMON)
-   for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i)
-   vmw_ldu_init(dev_priv, i);
-   else
-   vmw_ldu_init(dev_priv, 0);
+   for (i = 0; i < num_display_units; ++i) {
+   ret = vmw_ldu_init(dev_priv, i);
+   if (ret != 0)
+   goto err_free;
+   }
 
dev_priv->active_display_unit = vmw_du_legacy;
 
-- 
2.32.0



[PATCH 4/8] drm/vmwgfx: Fix fencing on SVGAv3

2022-03-02 Thread Zack Rusin
From: Zack Rusin 

Port of the vmwgfx to SVGAv3 lacked support for fencing. SVGAv3 removed
FIFO's and replaced them with command buffers and extra registers.
The initial version of SVGAv3 lacked support for most advanced features
(e.g. 3D) which made fences unnecessary. That is no longer the case,
especially as 3D support is being turned on.

Switch from FIFO commands and capabilities to command buffers and extra
registers to enable fences on SVGAv3.

Fixes: 2cd80dbd3551 ("drm/vmwgfx: Add basic support for SVGA3")
Signed-off-by: Zack Rusin 
Reviewed-by: Martin Krastev 
Reviewed-by: Maaz Mombasawala 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c   |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h   |  8 
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 28 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_irq.c   | 26 +
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |  8 +---
 5 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c
index a3bfbb6c3e14..bf1b394753da 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c
@@ -528,7 +528,7 @@ int vmw_cmd_send_fence(struct vmw_private *dev_priv, 
uint32_t *seqno)
*seqno = atomic_add_return(1, &dev_priv->marker_seq);
} while (*seqno == 0);
 
-   if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE)) {
+   if (!vmw_has_fences(dev_priv)) {
 
/*
 * Don't request hardware to send a fence. The
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 780da6147cf9..12eb4de41036 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -1683,4 +1683,12 @@ static inline void vmw_irq_status_write(struct 
vmw_private *vmw,
outl(status, vmw->io_start + SVGA_IRQSTATUS_PORT);
 }
 
+static inline bool vmw_has_fences(struct vmw_private *vmw)
+{
+   if ((vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS |
+ SVGA_CAP_CMD_BUFFERS_2)) != 0)
+   return true;
+   return (vmw_fifo_caps(vmw) & SVGA_FIFO_CAP_FENCE) != 0;
+}
+
 #endif
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index 59d6a2dd4c2e..66cc35dc223e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -82,6 +82,22 @@ fman_from_fence(struct vmw_fence_obj *fence)
return container_of(fence->base.lock, struct vmw_fence_manager, lock);
 }
 
+static u32 vmw_fence_goal_read(struct vmw_private *vmw)
+{
+   if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
+   return vmw_read(vmw, SVGA_REG_FENCE_GOAL);
+   else
+   return vmw_fifo_mem_read(vmw, SVGA_FIFO_FENCE_GOAL);
+}
+
+static void vmw_fence_goal_write(struct vmw_private *vmw, u32 value)
+{
+   if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
+   vmw_write(vmw, SVGA_REG_FENCE_GOAL, value);
+   else
+   vmw_fifo_mem_write(vmw, SVGA_FIFO_FENCE_GOAL, value);
+}
+
 /*
  * Note on fencing subsystem usage of irqs:
  * Typically the vmw_fences_update function is called
@@ -392,7 +408,7 @@ static bool vmw_fence_goal_new_locked(struct 
vmw_fence_manager *fman,
if (likely(!fman->seqno_valid))
return false;
 
-   goal_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE_GOAL);
+   goal_seqno = vmw_fence_goal_read(fman->dev_priv);
if (likely(passed_seqno - goal_seqno >= VMW_FENCE_WRAP))
return false;
 
@@ -400,9 +416,8 @@ static bool vmw_fence_goal_new_locked(struct 
vmw_fence_manager *fman,
list_for_each_entry(fence, &fman->fence_list, head) {
if (!list_empty(&fence->seq_passed_actions)) {
fman->seqno_valid = true;
-   vmw_fifo_mem_write(fman->dev_priv,
-  SVGA_FIFO_FENCE_GOAL,
-  fence->base.seqno);
+   vmw_fence_goal_write(fman->dev_priv,
+fence->base.seqno);
break;
}
}
@@ -434,13 +449,12 @@ static bool vmw_fence_goal_check_locked(struct 
vmw_fence_obj *fence)
if (dma_fence_is_signaled_locked(&fence->base))
return false;
 
-   goal_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE_GOAL);
+   goal_seqno = vmw_fence_goal_read(fman->dev_priv);
if (likely(fman->seqno_valid &&
   goal_seqno - fence->base.seqno < VMW_FENCE_WRAP))
return false;
 
-   vmw_fifo_mem_write(fman->dev_priv, SVGA_FIFO_FENCE_GOAL,
-  fence->base.seqno);
+   vmw_fence_goal_write(fman->dev_priv, fence->base.seqno);
fman->seqno_valid = true;
 
return true;
diff --git a/drivers/gpu/drm/

[PATCH 1/8] drm/vmwgfx: Add support for CursorMob and CursorBypass 4

2022-03-02 Thread Zack Rusin
From: Martin Krastev 

* Add support for CursorMob
* Add support for CursorBypass 4
* Refactor vmw_du_cursor_plane_atomic_update to be kms-helper-atomic
  -- move BO mappings to vmw_du_cursor_plane_prepare_fb
  -- move BO unmappings to vmw_du_cursor_plane_cleanup_fb

Cursor mobs are a new svga feature which enables support for large
cursors, e.g. large accessibility cursor on platforms with vmwgfx. It
also cleans up the cursor code and makes it more uniform with the rest
of modern guest backed objects support.

Signed-off-by: Martin Krastev 
Reviewed-by: Zack Rusin 
Reviewed-by: Maaz Mombasawala 
Signed-off-by: Zack Rusin 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c  |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h  |   6 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c  | 399 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h  |  28 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c  |  18 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c |  17 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c |  16 +-
 7 files changed, 382 insertions(+), 104 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 26eb5478394a..621231c66fd4 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**
  *
- * Copyright 2009-2016 VMware, Inc., Palo Alto, CA., USA
+ * Copyright 2009-2022 VMware, Inc., Palo Alto, CA., USA
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index ea3ecdda561d..780da6147cf9 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
 /**
  *
- * Copyright 2009-2021 VMware, Inc., Palo Alto, CA., USA
+ * Copyright 2009-2022 VMware, Inc., Palo Alto, CA., USA
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -101,6 +101,7 @@ struct vmw_fpriv {
  * struct vmw_buffer_object - TTM buffer object with vmwgfx additions
  * @base: The TTM buffer object
  * @res_tree: RB tree of resources using this buffer object as a backing MOB
+ * @base_mapped_count: ttm BO mapping count; used by KMS atomic helpers.
  * @cpu_writers: Number of synccpu write grabs. Protected by reservation when
  * increased. May be decreased without reservation.
  * @dx_query_ctx: DX context if this buffer object is used as a DX query MOB
@@ -111,6 +112,9 @@ struct vmw_fpriv {
 struct vmw_buffer_object {
struct ttm_buffer_object base;
struct rb_root res_tree;
+   /* For KMS atomic helpers: ttm bo mapping count */
+   atomic_t base_mapped_count;
+
atomic_t cpu_writers;
/* Not ref-counted.  Protected by binding_mutex */
struct vmw_resource *dx_query_ctx;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index bbd2f4ec08ec..9d82a7b49aed 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**
  *
- * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA
+ * Copyright 2009-2022 VMware, Inc., Palo Alto, CA., USA
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -41,7 +41,7 @@ void vmw_du_cleanup(struct vmw_display_unit *du)
struct vmw_private *dev_priv = vmw_priv(du->primary.dev);
drm_plane_cleanup(&du->primary);
if (vmw_cmd_supported(dev_priv))
-   drm_plane_cleanup(&du->cursor);
+   drm_plane_cleanup(&du->cursor.base);
 
drm_connector_unregister(&du->connector);
drm_crtc_cleanup(&du->crtc);
@@ -53,23 +53,43 @@ void vmw_du_cleanup(struct vmw_display_unit *du)
  * Display Unit Cursor functions
  */
 
-static int vmw_cursor_update_image(struct vmw_private *dev_priv,
-  u32 *image, u32 width, u32 height,
-  u32 hotspotX, u32 hotspotY)
+static void vmw_cursor_update_mob(struct vmw_private *dev_priv,
+ struct ttm_buffer_object *bo,
+ struct ttm_bo_kmap_obj *map,
+ u32 *image, u32 width, u32 height,
+ u32 hotspotX, u32 hotspotY);
+
+struct vmw_svga_fifo_cmd_define_cursor {
+   u32 cmd;
+   SVGAFifoCmdDefineAlphaCursor cursor;
+};
+
+static void vmw_cursor_update_image(struct vmw_private *dev_priv,
+

[PATCH 7/8] drm/vmwgfx: Implement MSI/MSI-X support for IRQs

2022-03-02 Thread Zack Rusin
From: Zack Rusin 

SVGAv3 deprecates legacy interrupts and adds support for MSI/MSI-X. With
MSI the driver visible side remains largely unchanged but with MSI-X
each interrupt gets delivered on its own vector.

Add support for MSI/MSI-X while preserving the old functionality for
SVGAv2. Code between the SVGAv2 and SVGAv3 is exactly the same, only
the number of available vectors changes, in particular between legacy
and MSI-X interrupts.

Signed-off-by: Zack Rusin 
Reviewed-by: Martin Krastev 
Reviewed-by: Maaz Mombasawala 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |  9 -
 drivers/gpu/drm/vmwgfx/vmwgfx_irq.c | 54 +
 3 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index f43afd56915e..791f9a5f3868 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -980,7 +980,7 @@ static int vmw_driver_load(struct vmw_private *dev_priv, 
u32 pci_id)
}
 
if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
-   ret = vmw_irq_install(&dev_priv->drm, pdev->irq);
+   ret = vmw_irq_install(dev_priv);
if (ret != 0) {
drm_err(&dev_priv->drm,
"Failed installing irq: %d\n", ret);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 12eb4de41036..be19aa6e1f13 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -65,6 +65,11 @@
 #define VMWGFX_PCI_ID_SVGA2  0x0405
 #define VMWGFX_PCI_ID_SVGA3  0x0406
 
+/*
+ * This has to match get_count_order(SVGA_IRQFLAG_MAX)
+ */
+#define VMWGFX_MAX_NUM_IRQS 6
+
 /*
  * Perhaps we should have sysfs entries for these.
  */
@@ -532,6 +537,8 @@ struct vmw_private {
bool has_mob;
spinlock_t hw_lock;
bool assume_16bpp;
+   u32 irqs[VMWGFX_MAX_NUM_IRQS];
+   u32 num_irq_vectors;
 
enum vmw_sm_type sm_type;
 
@@ -1158,7 +1165,7 @@ bool vmw_cmd_describe(const void *buf, u32 *size, char 
const **cmd);
  * IRQs and wating - vmwgfx_irq.c
  */
 
-extern int vmw_irq_install(struct drm_device *dev, int irq);
+extern int vmw_irq_install(struct vmw_private *dev_priv);
 extern void vmw_irq_uninstall(struct drm_device *dev);
 extern bool vmw_seqno_passed(struct vmw_private *dev_priv,
uint32_t seqno);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
index fe4732bf2c9d..482989b1f211 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
@@ -300,6 +300,7 @@ void vmw_irq_uninstall(struct drm_device *dev)
struct vmw_private *dev_priv = vmw_priv(dev);
struct pci_dev *pdev = to_pci_dev(dev->dev);
uint32_t status;
+   u32 i;
 
if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK))
return;
@@ -309,20 +310,61 @@ void vmw_irq_uninstall(struct drm_device *dev)
status = vmw_irq_status_read(dev_priv);
vmw_irq_status_write(dev_priv, status);
 
-   free_irq(pdev->irq, dev);
+   for (i = 0; i < dev_priv->num_irq_vectors; ++i)
+   free_irq(dev_priv->irqs[i], dev);
+
+   pci_free_irq_vectors(pdev);
+   dev_priv->num_irq_vectors = 0;
 }
 
 /**
  * vmw_irq_install - Install the irq handlers
  *
- * @dev:  Pointer to the drm device.
- * @irq:  The irq number.
+ * @dev_priv:  Pointer to the vmw_private device.
  * Return:  Zero if successful. Negative number otherwise.
  */
-int vmw_irq_install(struct drm_device *dev, int irq)
+int vmw_irq_install(struct vmw_private *dev_priv)
 {
+   struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+   struct drm_device *dev = &dev_priv->drm;
+   int ret;
+   int nvec;
+   int i = 0;
+
+   BUILD_BUG_ON((SVGA_IRQFLAG_MAX >> VMWGFX_MAX_NUM_IRQS) != 1);
+   BUG_ON(VMWGFX_MAX_NUM_IRQS != get_count_order(SVGA_IRQFLAG_MAX));
+
+   nvec = pci_alloc_irq_vectors(pdev, 1, VMWGFX_MAX_NUM_IRQS,
+PCI_IRQ_ALL_TYPES);
+
+   if (nvec <= 0) {
+   drm_err(&dev_priv->drm,
+   "IRQ's are unavailable, nvec: %d\n", nvec);
+   goto done;
+   }
+
vmw_irq_preinstall(dev);
 
-   return request_threaded_irq(irq, vmw_irq_handler, vmw_thread_fn,
-   IRQF_SHARED, VMWGFX_DRIVER_NAME, dev);
+   for (i = 0; i < nvec; ++i) {
+   ret = pci_irq_vector(pdev, i);
+   if (ret < 0) {
+   drm_err(&dev_priv->drm,
+   "failed getting irq vector: %d\n", ret);
+   goto done;
+   }
+   dev_priv->irqs[i] = ret;
+
+   ret = request_threaded_irq(dev_priv->irqs[i], vmw_irq_handler, 
vmw_thread_fn,
+  

[PATCH 5/8] drm/vmwgfx: Allow querying of the SVGA PCI id from the userspace

2022-03-02 Thread Zack Rusin
From: Zack Rusin 

Mesa3D loaders require knowledge of the devices PCI id. SVGAv2 and v3
have different PCI id's, but the same driver is used to handle them both.
To allow Mesa3D svga driver to be loaded automatically for both SVGAv2
and SVGAv3 make the kernel return the PCI id of the currently running
device.

Signed-off-by: Zack Rusin 
Reviewed-by: Martin Krastev 
Reviewed-by: Maaz Mombasawala 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 27 +++
 include/uapi/drm/vmwgfx_drm.h |  9 -
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index 471da2b4c177..a1da5678c731 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**
  *
- * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA
+ * Copyright 2009-2022 VMware, Inc., Palo Alto, CA., USA
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -27,9 +27,11 @@
 
 #include "vmwgfx_drv.h"
 #include "vmwgfx_devcaps.h"
-#include 
 #include "vmwgfx_kms.h"
 
+#include 
+#include 
+
 int vmw_getparam_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv)
 {
@@ -62,17 +64,15 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data,
break;
case DRM_VMW_PARAM_FIFO_HW_VERSION:
{
-   if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS)) {
+   if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS))
param->value = SVGA3D_HWVERSION_WS8_B1;
-   break;
-   }
-
-   param->value =
-   vmw_fifo_mem_read(dev_priv,
- ((vmw_fifo_caps(dev_priv) &
-   SVGA_FIFO_CAP_3D_HWVERSION_REVISED) 
?
-  
SVGA_FIFO_3D_HWVERSION_REVISED :
-  SVGA_FIFO_3D_HWVERSION));
+   else
+   param->value = vmw_fifo_mem_read(
+  dev_priv,
+  ((vmw_fifo_caps(dev_priv) &
+
SVGA_FIFO_CAP_3D_HWVERSION_REVISED) ?
+   
SVGA_FIFO_3D_HWVERSION_REVISED :
+   
SVGA_FIFO_3D_HWVERSION));
break;
}
case DRM_VMW_PARAM_MAX_SURF_MEMORY:
@@ -108,6 +108,9 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data,
case DRM_VMW_PARAM_GL43:
param->value = has_gl43_context(dev_priv);
break;
+   case DRM_VMW_PARAM_DEVICE_ID:
+   param->value = to_pci_dev(dev_priv->drm.dev)->device;
+   break;
default:
return -EINVAL;
}
diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h
index 8277644c1144..26549c86a91f 100644
--- a/include/uapi/drm/vmwgfx_drm.h
+++ b/include/uapi/drm/vmwgfx_drm.h
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright © 2009-2015 VMware, Inc., Palo Alto, CA., USA
+ * Copyright © 2009-2022 VMware, Inc., Palo Alto, CA., USA
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -92,6 +92,12 @@ extern "C" {
  *
  * DRM_VMW_PARAM_SM5
  * SM5 support is enabled.
+ *
+ * DRM_VMW_PARAM_GL43
+ * SM5.1+GL4.3 support is enabled.
+ *
+ * DRM_VMW_PARAM_DEVICE_ID
+ * PCI ID of the underlying SVGA device.
  */
 
 #define DRM_VMW_PARAM_NUM_STREAMS  0
@@ -111,6 +117,7 @@ extern "C" {
 #define DRM_VMW_PARAM_SM4_114
 #define DRM_VMW_PARAM_SM5  15
 #define DRM_VMW_PARAM_GL43 16
+#define DRM_VMW_PARAM_DEVICE_ID17
 
 /**
  * enum drm_vmw_handle_type - handle type for ref ioctls
-- 
2.32.0



[PATCH 8/8] drm/vmwgfx: Stop using surface dma commands on most configurations

2022-03-02 Thread Zack Rusin
From: Zack Rusin 

Initial version of guest backed objects in the host had some performance
issues that made using surface-dma's instead of direct copies faster.
Surface dma's force a migration to vram which at best is slow and at
worst is impossible (e.g. on svga3 where there's not enough vram
to migrate fb's to it).

Slowly migrate away from surface dma's to direct copies by limiting
their usage to systems with more than 32MB of vram.

Signed-off-by: Zack Rusin 
Reviewed-by: Maaz Mombasawala 
Reviewed-by: Martin Krastev 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index 42b5ecb0c5e9..eb014b97d156 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -138,6 +138,11 @@ static void vmw_stdu_destroy(struct 
vmw_screen_target_display_unit *stdu);
  * Screen Target Display Unit CRTC Functions
  */
 
+static bool vmw_stdu_use_cpu_blit(const struct vmw_private *vmw)
+{
+   return !(vmw->capabilities & SVGA_CAP_3D) || vmw->vram_size < (32 * 
1024 * 1024);
+}
+
 
 /**
  * vmw_stdu_crtc_destroy - cleans up the STDU
@@ -689,7 +694,7 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
container_of(vfb, struct vmw_framebuffer_bo, base)->buffer;
struct vmw_stdu_dirty ddirty;
int ret;
-   bool cpu_blit = !(dev_priv->capabilities & SVGA_CAP_3D);
+   bool cpu_blit = vmw_stdu_use_cpu_blit(dev_priv);
DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
 
/*
@@ -1164,7 +1169,7 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane,
 * so cache these mappings
 */
if (vps->content_fb_type == SEPARATE_BO &&
-   !(dev_priv->capabilities & SVGA_CAP_3D))
+   vmw_stdu_use_cpu_blit(dev_priv))
vps->cpp = new_fb->pitches[0] / new_fb->width;
 
return 0;
@@ -1368,7 +1373,7 @@ static int vmw_stdu_plane_update_bo(struct vmw_private 
*dev_priv,
bo_update.base.vfb = vfb;
bo_update.base.out_fence = out_fence;
bo_update.base.mutex = NULL;
-   bo_update.base.cpu_blit = !(dev_priv->capabilities & SVGA_CAP_3D);
+   bo_update.base.cpu_blit = vmw_stdu_use_cpu_blit(dev_priv);
bo_update.base.intr = false;
 
/*
-- 
2.32.0



[PATCH 6/8] drm/vmwgfx: Initialize drm_mode_fb_cmd2

2022-03-02 Thread Zack Rusin
From: Zack Rusin 

Transition to drm_mode_fb_cmd2 from drm_mode_fb_cmd left the structure
unitialized. drm_mode_fb_cmd2 adds a few additional members, e.g. flags
and modifiers which were never initialized. Garbage in those members
can cause random failures during the bringup of the fbcon.

Initializing the structure fixes random blank screens after bootup due
to flags/modifiers mismatches during the fbcon bring up.

Fixes: dabdcdc9822a ("drm/vmwgfx: Switch to mode_cmd2")
Signed-off-by: Zack Rusin 
Cc: Daniel Vetter 
Cc:  # v4.10+
Reviewed-by: Martin Krastev 
Reviewed-by: Maaz Mombasawala 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index 8ee34576c7d0..adf17c740656 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -483,7 +483,7 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
 
 static int vmw_fb_kms_framebuffer(struct fb_info *info)
 {
-   struct drm_mode_fb_cmd2 mode_cmd;
+   struct drm_mode_fb_cmd2 mode_cmd = {0};
struct vmw_fb_par *par = info->par;
struct fb_var_screeninfo *var = &info->var;
struct drm_framebuffer *cur_fb;
-- 
2.32.0



Re: [PATCH v12 1/6] drm: Add arch arm64 for drm_clflush_virt_range

2022-03-02 Thread Michael Cheng

Thanks for the feedback Robin!

Sorry my choices of word weren't that great, but what I meant is to 
understand how ARM flushes a range of dcache for device drivers, and not 
an equal to x86 clflush.


I believe the concern is if the CPU writes an update, that update might 
only be sitting in the CPU cache and never make it to device memory 
where the device can see it; there are specific places that we are 
supposed to flush the CPU caches to make sure our updates are visible to 
the hardware.


+Matt Roper

Matt, Lucas, any feed back here?

On 2022-03-02 4:49 a.m., Robin Murphy wrote:

On 2022-02-25 19:27, Michael Cheng wrote:

Hi Robin,

[ +arm64 maintainers for their awareness, which would have been a 
good thing to do from the start ]


  * Thanks for adding the arm64 maintainer and sorry I didn't rope them
    in sooner.

Why does i915 need to ensure the CPU's instruction cache is coherent 
with its data cache? Is it a self-modifying driver?


  * Also thanks for pointing this out. Initially I was using
    dcache_clean_inval_poc, which seem to be the equivalently to what
    x86 is doing for dcache flushing, but it was giving me build errors
    since its not on the global list of kernel symbols. And after
    revisiting the documentation for caches_clean_inval_pou, it won't
    fly for what we are trying to do. Moving forward, what would you (or
    someone in the ARM community) suggest we do? Could it be possible to
    export dcache_clean_inval_poc as a global symbol?


Unlikely, unless something with a legitimate need for CPU-centric 
cache maintenance like kexec or CPU hotplug ever becomes modular.


In the case of a device driver, it's not even the basic issues of 
assuming to find direct equivalents to x86 semantics in other CPU 
architectures, or effectively reinventing parts of the DMA API, it's 
even bigger than that. Once you move from being integrated in a single 
vendor's system architecture to being on a discrete card, you 
fundamentally *no longer have any control over cache coherency*. 
Whether the host CPU architecture happens to be AArch64, RISC-V, or 
whatever doesn't really matter, you're at the mercy of 3rd-party PCIe 
and interconnect IP vendors, and SoC integrators. You'll find yourself 
in systems where PCIe simply cannot snoop any caches, where you'd 
better have the correct DMA API calls in place to have any hope of 
even the most basic functionality working properly; you'll find 
yourself in systems where even if the PCIe root complex claims to 
support No Snoop, your uncached traffic will still end up snooping 
stale data that got prefetched back into caches you thought you'd 
invalidated; you'll find yourself in systems where your memory 
attributes may or may not get forcibly rewritten by an IOMMU depending 
on the kernel config and/or command line.


It's not about simply finding a substitute for clflush, it's that the 
reasons you have for using clflush in the first place can no longer be 
assumed to be valid.


Robin.


On 2022-02-25 10:24 a.m., Robin Murphy wrote:
[ +arm64 maintainers for their awareness, which would have been a 
good thing to do from the start ]


On 2022-02-25 03:24, Michael Cheng wrote:

Add arm64 support for drm_clflush_virt_range. caches_clean_inval_pou
performs a flush by first performing a clean, follow by an 
invalidation

operation.

v2 (Michael Cheng): Use correct macro for cleaning and invalidation 
the

    dcache. Thanks Tvrtko for the suggestion.

v3 (Michael Cheng): Replace asm/cacheflush.h with linux/cacheflush.h

v4 (Michael Cheng): Arm64 does not export dcache_clean_inval_poc as a
    symbol that could be use by other modules, thus use
    caches_clean_inval_pou instead. Also this version
    removes include for cacheflush, since its already
    included base on architecture type.

Signed-off-by: Michael Cheng 
Reviewed-by: Matt Roper 
---
  drivers/gpu/drm/drm_cache.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index c3e6e615bf09..81c28714f930 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -174,6 +174,11 @@ drm_clflush_virt_range(void *addr, unsigned 
long length)

    if (wbinvd_on_all_cpus())
  pr_err("Timed out waiting for cache flush\n");
+
+#elif defined(CONFIG_ARM64)
+    void *end = addr + length;
+    caches_clean_inval_pou((unsigned long)addr, (unsigned long)end);


Why does i915 need to ensure the CPU's instruction cache is coherent 
with its data cache? Is it a self-modifying driver?


Robin.

(Note that the above is somewhat of a loaded question, and I do 
actually have half an idea of what you're trying to do here and why 
it won't fly, but I'd like to at least assume you've read the 
documentation of the function you decided was OK to use)



+
  #else
  WARN_ONCE(1, "Architecture has no drm_cache.c support\n");
  #endif


Re: [RFC PATCH] drm/panel: simple: panel-dpi: use bus-format to set bpc and bus_format

2022-03-02 Thread Marek Vasut

On 3/2/22 15:21, Maxime Ripard wrote:

Hi,


Hi,


Please try to avoid top posting

On Wed, Feb 23, 2022 at 04:25:19PM +0100, Max Krummenacher wrote:

The goal here is to set the element bus_format in the struct
panel_desc. This is an enum with the possible values defined in
include/uapi/linux/media-bus-format.h.

The enum values are not constructed in a way that you could calculate
the value from color channel width/shift/mapping/whatever. You rather
would have to check if the combination of color channel
width/shift/mapping/whatever maps to an existing value and otherwise
EINVAL out.

I don't see the value in having yet another way of how this
information can be specified and then having to write a more
complicated parser which maps the dt data to bus_format.


Generally speaking, sending an RFC without explicitly stating what you
want a comment on isn't very efficient.


Isn't that what RFC stands for -- Request For Comment ?


That being said, what I (and I can only assume Marek) don't like is the
string encoding. Especially when the similar bus-type property uses a
integer with the various available bus options we have.


Right, the string encoding isn't good.


Having an integer, with a set of defines that you would map to the
proper MEDIA_BUS_* would be more efficient and more elegant.

That being said, the first question that needs to be answered is why
does this have to be in the DT in the first place?


Because panel-simple panel-dpi , you may need to specify the bus format 
between the last bridge and the panel .


  1   2   >