All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Update 128b/132b MST Slot Information
@ 2021-08-27 23:43 Fangzhi Zuo
  2021-08-27 23:43 ` [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format Fangzhi Zuo
  2021-08-27 23:43 ` [PATCH 2/2] drm/amdgpu: Example Usage in AMDGPU Fangzhi Zuo
  0 siblings, 2 replies; 37+ messages in thread
From: Fangzhi Zuo @ 2021-08-27 23:43 UTC (permalink / raw)
  To: dri-devel
  Cc: lyude, harry.wentland, Nicholas.Kazlauskas, wayne.lin, Fangzhi Zuo

128b/132b MST start slot information is not the same as 8b/10b.
Update based on encoding format after link detection or topology change.

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

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

-- 
2.25.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-08-27 23:43 [PATCH 0/2] Update 128b/132b MST Slot Information Fangzhi Zuo
@ 2021-08-27 23:43 ` Fangzhi Zuo
  2021-08-28  4:09     ` kernel test robot
  2021-08-30 20:00   ` Lyude Paul
  2021-08-27 23:43 ` [PATCH 2/2] drm/amdgpu: Example Usage in AMDGPU Fangzhi Zuo
  1 sibling, 2 replies; 37+ messages in thread
From: Fangzhi Zuo @ 2021-08-27 23:43 UTC (permalink / raw)
  To: dri-devel
  Cc: lyude, harry.wentland, Nicholas.Kazlauskas, wayne.lin, Fangzhi Zuo

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

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

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

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


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 2/2] drm/amdgpu: Example Usage in AMDGPU
  2021-08-27 23:43 [PATCH 0/2] Update 128b/132b MST Slot Information Fangzhi Zuo
  2021-08-27 23:43 ` [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format Fangzhi Zuo
@ 2021-08-27 23:43 ` Fangzhi Zuo
  2021-08-28 11:54     ` kernel test robot
  1 sibling, 1 reply; 37+ messages in thread
From: Fangzhi Zuo @ 2021-08-27 23:43 UTC (permalink / raw)
  To: dri-devel
  Cc: lyude, harry.wentland, Nicholas.Kazlauskas, wayne.lin, Fangzhi Zuo

1. Decide MST Link Encoding Cap
2. Update MST First Link Slot Information

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

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


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-08-27 23:43 ` [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format Fangzhi Zuo
@ 2021-08-28  4:09     ` kernel test robot
  2021-08-30 20:00   ` Lyude Paul
  1 sibling, 0 replies; 37+ messages in thread
From: kernel test robot @ 2021-08-28  4:09 UTC (permalink / raw)
  To: Fangzhi Zuo, dri-devel
  Cc: kbuild-all, lyude, harry.wentland, Nicholas.Kazlauskas,
	wayne.lin, Fangzhi Zuo

[-- Attachment #1: Type: text/plain, Size: 2521 bytes --]

Hi Fangzhi,

Thank you for the patch! Perhaps something to improve:

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

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

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

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


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

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

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33995 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format
@ 2021-08-28  4:09     ` kernel test robot
  0 siblings, 0 replies; 37+ messages in thread
From: kernel test robot @ 2021-08-28  4:09 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2576 bytes --]

Hi Fangzhi,

Thank you for the patch! Perhaps something to improve:

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

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

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

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


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

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

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

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 33995 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 2/2] drm/amdgpu: Example Usage in AMDGPU
  2021-08-27 23:43 ` [PATCH 2/2] drm/amdgpu: Example Usage in AMDGPU Fangzhi Zuo
@ 2021-08-28 11:54     ` kernel test robot
  0 siblings, 0 replies; 37+ messages in thread
From: kernel test robot @ 2021-08-28 11:54 UTC (permalink / raw)
  To: Fangzhi Zuo, dri-devel
  Cc: llvm, kbuild-all, lyude, harry.wentland, Nicholas.Kazlauskas,
	wayne.lin, Fangzhi Zuo

[-- Attachment #1: Type: text/plain, Size: 2934 bytes --]

Hi Fangzhi,

Thank you for the patch! Yet something to improve:

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

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

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_mst_types.c:447:23: error: implicit declaration of function 'dc_link_dp_mst_decide_link_encoding_format' [-Werror,-Wimplicit-function-declaration]
                   link_encoding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
                                       ^
>> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_mst_types.c:448:3: error: implicit declaration of function 'drm_dp_mst_update_coding_cap' [-Werror,-Wimplicit-function-declaration]
                   drm_dp_mst_update_coding_cap(&aconnector->mst_mgr, link_encoding_cap);
                   ^
   2 errors generated.


vim +/dc_link_dp_mst_decide_link_encoding_format +447 drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_mst_types.c

   441	
   442	void get_mst_link_encoding_cap(struct amdgpu_dm_connector *aconnector)
   443	{
   444		u8 link_encoding_cap;
   445	
   446		if (aconnector->dc_link->type == dc_connection_mst_branch) {
 > 447			link_encoding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
 > 448			drm_dp_mst_update_coding_cap(&aconnector->mst_mgr, link_encoding_cap);
   449		}
   450	}
   451	

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 38762 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 2/2] drm/amdgpu: Example Usage in AMDGPU
@ 2021-08-28 11:54     ` kernel test robot
  0 siblings, 0 replies; 37+ messages in thread
From: kernel test robot @ 2021-08-28 11:54 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2992 bytes --]

Hi Fangzhi,

Thank you for the patch! Yet something to improve:

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

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

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_mst_types.c:447:23: error: implicit declaration of function 'dc_link_dp_mst_decide_link_encoding_format' [-Werror,-Wimplicit-function-declaration]
                   link_encoding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
                                       ^
>> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_mst_types.c:448:3: error: implicit declaration of function 'drm_dp_mst_update_coding_cap' [-Werror,-Wimplicit-function-declaration]
                   drm_dp_mst_update_coding_cap(&aconnector->mst_mgr, link_encoding_cap);
                   ^
   2 errors generated.


vim +/dc_link_dp_mst_decide_link_encoding_format +447 drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_mst_types.c

   441	
   442	void get_mst_link_encoding_cap(struct amdgpu_dm_connector *aconnector)
   443	{
   444		u8 link_encoding_cap;
   445	
   446		if (aconnector->dc_link->type == dc_connection_mst_branch) {
 > 447			link_encoding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
 > 448			drm_dp_mst_update_coding_cap(&aconnector->mst_mgr, link_encoding_cap);
   449		}
   450	}
   451	

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

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 38762 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-08-27 23:43 ` [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format Fangzhi Zuo
  2021-08-28  4:09     ` kernel test robot
@ 2021-08-30 20:00   ` Lyude Paul
  2021-08-31 19:44     ` Zuo, Jerry
  1 sibling, 1 reply; 37+ messages in thread
From: Lyude Paul @ 2021-08-30 20:00 UTC (permalink / raw)
  To: Fangzhi Zuo, dri-devel; +Cc: harry.wentland, Nicholas.Kazlauskas, wayne.lin

On Fri, 2021-08-27 at 19:43 -0400, Fangzhi Zuo wrote:
> 8b/10b encoding format requires to reserve the first slot for
> recording metadata. Real data transmission starts from the second slot,
> with a total of available 63 slots available.
> 
> In 128b/132b encoding format, metadata is transmitted separately
> in LLCP packet before MTP. Real data transmission starts from
> the first slot, with a total of 64 slots available.
> 
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 27 ++++++++++++++++++++-------
>  include/drm/drm_dp_mst_helper.h       |  9 +++++++++
>  2 files changed, 29 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 86d13d6bc463..30544801d2b8 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3370,7 +3370,7 @@ int drm_dp_update_payload_part1(struct
> drm_dp_mst_topology_mgr *mgr)
>         struct drm_dp_payload req_payload;
>         struct drm_dp_mst_port *port;
>         int i, j;
> -       int cur_slots = 1;
> +       int cur_slots = mgr->start_slot;
>         bool skip;
>  
>         mutex_lock(&mgr->payload_lock);
> @@ -4323,7 +4323,7 @@ int drm_dp_find_vcpi_slots(struct
> drm_dp_mst_topology_mgr *mgr,
>         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
>  
>         /* max. time slots - one slot for MTP header */
> -       if (num_slots > 63)
> +       if (num_slots > mgr->total_avail_slots)
>                 return -ENOSPC;
>         return num_slots;
>  }
> @@ -4335,7 +4335,7 @@ static int drm_dp_init_vcpi(struct
> drm_dp_mst_topology_mgr *mgr,
>         int ret;
>  
>         /* max. time slots - one slot for MTP header */
> -       if (slots > 63)
> +       if (slots > mgr->total_avail_slots)
>                 return -ENOSPC;
>  
>         vcpi->pbn = pbn;
> @@ -4509,6 +4509,17 @@ int drm_dp_atomic_release_vcpi_slots(struct
> drm_atomic_state *state,
>  }
>  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>  
> +void drm_dp_mst_update_encoding_cap(struct drm_dp_mst_topology_mgr *mgr,
> uint8_t link_encoding_cap)
> +{
> +       if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
> +               mgr->total_avail_slots = 64;
> +               mgr->start_slot = 0;
> +       }
> +       DRM_DEBUG_KMS("%s encoding format determined\n",
> +                     (link_encoding_cap == DP_CAP_ANSI_128B132B) ?
> "128b/132b" : "8b/10b");
> +}
> +EXPORT_SYMBOL(drm_dp_mst_update_encoding_cap);
> +

This seems to be missing kdocs, can you fix that?

Also - I'm not convinced this is all of the work we have to do, as there's no
locking taking place here in this function. If we're changing the number of
available VCPI slots that we have, we need to be able to factor that into the
atomic check logic which means that we can't rely on mgr->* for any kind of
data that isn't guaranteed to remain consistent throughout the lifetime of the
driver or topology. (Note that some of the old MST code didn't follow this
logic, so I wouldn't be surprised if there's still exceptions to this we need
to clean up).

Note that I still expect we'll have to keep some sort of track of the current
total slot count in the topology mgr, but that should be reflecting the
currently programmed state and not be relied on from our atomic check.

IMHO - the correct way we should go about adding support for this is to add
something into drm_dp_mst_topology_state and integrate this into the atomic
check helpers.

>  /**
>   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>   * @mgr: manager for this port
> @@ -4540,8 +4551,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> drm_dp_mst_topology_mgr *mgr,
>  
>         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
>         if (ret) {
> -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63
> ret=%d\n",
> -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=%d
> ret=%d\n",
> +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> >total_avail_slots, ret);
>                 drm_dp_mst_topology_put_port(port);
>                 goto out;
>         }
> @@ -5228,7 +5239,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> drm_dp_mst_topology_mgr *mgr,
>                                          struct drm_dp_mst_topology_state
> *mst_state)
>  {
>         struct drm_dp_vcpi_allocation *vcpi;
> -       int avail_slots = 63, payload_count = 0;
> +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
>  
>         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>                 /* Releasing VCPI is always OK-even if the port is gone */
> @@ -5257,7 +5268,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> drm_dp_mst_topology_mgr *mgr,
>                 }
>         }
>         drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d
> used=%d\n",
> -                      mgr, mst_state, avail_slots, 63 - avail_slots);
> +                      mgr, mst_state, avail_slots, mgr->total_avail_slots -
> avail_slots);
>  
>         return 0;
>  }
> @@ -5529,6 +5540,8 @@ int drm_dp_mst_topology_mgr_init(struct
> drm_dp_mst_topology_mgr *mgr,
>         if (!mgr->proposed_vcpis)
>                 return -ENOMEM;
>         set_bit(0, &mgr->payload_mask);
> +       mgr->total_avail_slots = 63;
> +       mgr->start_slot = 1;
>  
>         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>         if (mst_state == NULL)
> diff --git a/include/drm/drm_dp_mst_helper.h
> b/include/drm/drm_dp_mst_helper.h
> index ddb9231d0309..eac5ce48f214 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -661,6 +661,15 @@ struct drm_dp_mst_topology_mgr {
>          */
>         int pbn_div;
>  
> +       /**
> +        * @total_avail_slots: available slots for data transmission
> +        */
> +       u8 total_avail_slots;
> +       /**
> +        * @start_slot: first slot index for data transmission
> +        */
> +       u8 start_slot;
> +
>         /**
>          * @funcs: Atomic helper callbacks
>          */

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* RE: [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-08-30 20:00   ` Lyude Paul
@ 2021-08-31 19:44     ` Zuo, Jerry
  2021-08-31 20:19       ` Lyude Paul
                         ` (2 more replies)
  0 siblings, 3 replies; 37+ messages in thread
From: Zuo, Jerry @ 2021-08-31 19:44 UTC (permalink / raw)
  To: Lyude Paul, dri-devel; +Cc: Wentland, Harry, Kazlauskas, Nicholas, Lin, Wayne

[AMD Official Use Only]

> -----Original Message-----
> From: Lyude Paul <lyude@redhat.com>
> Sent: August 30, 2021 4:00 PM
> To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org
> Cc: Wentland, Harry <Harry.Wentland@amd.com>; Kazlauskas, Nicholas
> <Nicholas.Kazlauskas@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>
> Subject: Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based
> on Encoding Format
>
> On Fri, 2021-08-27 at 19:43 -0400, Fangzhi Zuo wrote:
> > 8b/10b encoding format requires to reserve the first slot for
> > recording metadata. Real data transmission starts from the second
> > slot, with a total of available 63 slots available.
> >
> > In 128b/132b encoding format, metadata is transmitted separately in
> > LLCP packet before MTP. Real data transmission starts from the first
> > slot, with a total of 64 slots available.
> >
> > Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> > ---
> >  drivers/gpu/drm/drm_dp_mst_topology.c | 27
> > ++++++++++++++++++++-------
> >  include/drm/drm_dp_mst_helper.h       |  9 +++++++++
> >  2 files changed, 29 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> > b/drivers/gpu/drm/drm_dp_mst_topology.c
> > index 86d13d6bc463..30544801d2b8 100644
> > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > @@ -3370,7 +3370,7 @@ int drm_dp_update_payload_part1(struct
> > drm_dp_mst_topology_mgr *mgr)
> >         struct drm_dp_payload req_payload;
> >         struct drm_dp_mst_port *port;
> >         int i, j;
> > -       int cur_slots = 1;
> > +       int cur_slots = mgr->start_slot;
> >         bool skip;
> >
> >         mutex_lock(&mgr->payload_lock); @@ -4323,7 +4323,7 @@ int
> > drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
> >         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
> >
> >         /* max. time slots - one slot for MTP header */
> > -       if (num_slots > 63)
> > +       if (num_slots > mgr->total_avail_slots)
> >                 return -ENOSPC;
> >         return num_slots;
> >  }
> > @@ -4335,7 +4335,7 @@ static int drm_dp_init_vcpi(struct
> > drm_dp_mst_topology_mgr *mgr,
> >         int ret;
> >
> >         /* max. time slots - one slot for MTP header */
> > -       if (slots > 63)
> > +       if (slots > mgr->total_avail_slots)
> >                 return -ENOSPC;
> >
> >         vcpi->pbn = pbn;
> > @@ -4509,6 +4509,17 @@ int drm_dp_atomic_release_vcpi_slots(struct
> > drm_atomic_state *state,
> >  }
> >  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
> >
> > +void drm_dp_mst_update_encoding_cap(struct
> drm_dp_mst_topology_mgr
> > +*mgr,
> > uint8_t link_encoding_cap)
> > +{
> > +       if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
> > +               mgr->total_avail_slots = 64;
> > +               mgr->start_slot = 0;
> > +       }
> > +       DRM_DEBUG_KMS("%s encoding format determined\n",
> > +                     (link_encoding_cap == DP_CAP_ANSI_128B132B) ?
> > "128b/132b" : "8b/10b");
> > +}
> > +EXPORT_SYMBOL(drm_dp_mst_update_encoding_cap);
> > +
>
> This seems to be missing kdocs, can you fix that?
>
> Also - I'm not convinced this is all of the work we have to do, as there's no
> locking taking place here in this function. If we're changing the number of
> available VCPI slots that we have, we need to be able to factor that into the
> atomic check logic which means that we can't rely on mgr->* for any kind of
> data that isn't guaranteed to remain consistent throughout the lifetime of the
> driver or topology. (Note that some of the old MST code didn't follow this
> logic, so I wouldn't be surprised if there's still exceptions to this we need to
> clean up).
>
> Note that I still expect we'll have to keep some sort of track of the current
> total slot count in the topology mgr, but that should be reflecting the
> currently programmed state and not be relied on from our atomic check.
>

Thanks Lyude for your comments.

Seems I should keep existing code to keep track of current slot status in mgr.
That information is getting updated each time when topology change detected.
That slot information saved in mgr is a sort of static, and could only be used
for debug purpose to track what is the current encoding format.

> IMHO - the correct way we should go about adding support for this is to add
> something into drm_dp_mst_topology_state and integrate this into the
> atomic check helpers.

The slot information should also be added into drm_dp_mst_topology_state to
reflect the real-time slot status.

I'd like to confirm the best place to get slot count info. updated.
Should the update be done within &drm_mode_config_funcs. atomic_check(),
before new stream is created, OR
should be updated within drm_dp_mst_atomic_check() ?

The updated slot count will be used in drm_dp_mst_atomic_check() to check slot limit,
and in drm_dp_update_payload_part1() as initial cur_slots.

>
> >  /**
> >   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
> >   * @mgr: manager for this port
> > @@ -4540,8 +4551,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> > drm_dp_mst_topology_mgr *mgr,
> >
> >         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
> >         if (ret) {
> > -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > max=63 ret=%d\n",
> > -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> > +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > +max=%d
> > ret=%d\n",
> > +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> > >total_avail_slots, ret);
> >                 drm_dp_mst_topology_put_port(port);
> >                 goto out;
> >         }
> > @@ -5228,7 +5239,7 @@
> drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > drm_dp_mst_topology_mgr *mgr,
> >                                          struct
> > drm_dp_mst_topology_state
> > *mst_state)
> >  {
> >         struct drm_dp_vcpi_allocation *vcpi;
> > -       int avail_slots = 63, payload_count = 0;
> > +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
> >
> >         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
> >                 /* Releasing VCPI is always OK-even if the port is
> > gone */ @@ -5257,7 +5268,7 @@
> > drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > drm_dp_mst_topology_mgr *mgr,
> >                 }
> >         }
> >         drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI
> > avail=%d used=%d\n",
> > -                      mgr, mst_state, avail_slots, 63 - avail_slots);
> > +                      mgr, mst_state, avail_slots,
> > +mgr->total_avail_slots -
> > avail_slots);
> >
> >         return 0;
> >  }
> > @@ -5529,6 +5540,8 @@ int drm_dp_mst_topology_mgr_init(struct
> > drm_dp_mst_topology_mgr *mgr,
> >         if (!mgr->proposed_vcpis)
> >                 return -ENOMEM;
> >         set_bit(0, &mgr->payload_mask);
> > +       mgr->total_avail_slots = 63;
> > +       mgr->start_slot = 1;
> >
> >         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
> >         if (mst_state == NULL)
> > diff --git a/include/drm/drm_dp_mst_helper.h
> > b/include/drm/drm_dp_mst_helper.h index ddb9231d0309..eac5ce48f214
> > 100644
> > --- a/include/drm/drm_dp_mst_helper.h
> > +++ b/include/drm/drm_dp_mst_helper.h
> > @@ -661,6 +661,15 @@ struct drm_dp_mst_topology_mgr {
> >          */
> >         int pbn_div;
> >
> > +       /**
> > +        * @total_avail_slots: available slots for data transmission
> > +        */
> > +       u8 total_avail_slots;
> > +       /**
> > +        * @start_slot: first slot index for data transmission
> > +        */
> > +       u8 start_slot;
> > +
> >         /**
> >          * @funcs: Atomic helper callbacks
> >          */
>
> --
> Cheers,
>  Lyude Paul (she/her)
>  Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-08-31 19:44     ` Zuo, Jerry
@ 2021-08-31 20:19       ` Lyude Paul
  2021-08-31 22:44       ` Lyude Paul
  2021-08-31 22:45       ` [PATCH 1/2] " Lyude Paul
  2 siblings, 0 replies; 37+ messages in thread
From: Lyude Paul @ 2021-08-31 20:19 UTC (permalink / raw)
  To: Zuo, Jerry, dri-devel; +Cc: Wentland, Harry, Kazlauskas, Nicholas, Lin, Wayne

On Tue, 2021-08-31 at 19:44 +0000, Zuo, Jerry wrote:
> [AMD Official Use Only]
> 
> > -----Original Message-----
> > From: Lyude Paul <lyude@redhat.com>
> > Sent: August 30, 2021 4:00 PM
> > To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org
> > Cc: Wentland, Harry <Harry.Wentland@amd.com>; Kazlauskas, Nicholas
> > <Nicholas.Kazlauskas@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>
> > Subject: Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based
> > on Encoding Format
> > 
> > On Fri, 2021-08-27 at 19:43 -0400, Fangzhi Zuo wrote:
> > > 8b/10b encoding format requires to reserve the first slot for
> > > recording metadata. Real data transmission starts from the second
> > > slot, with a total of available 63 slots available.
> > > 
> > > In 128b/132b encoding format, metadata is transmitted separately in
> > > LLCP packet before MTP. Real data transmission starts from the first
> > > slot, with a total of 64 slots available.
> > > 
> > > Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> > > ---
> > >  drivers/gpu/drm/drm_dp_mst_topology.c | 27
> > > ++++++++++++++++++++-------
> > >  include/drm/drm_dp_mst_helper.h       |  9 +++++++++
> > >  2 files changed, 29 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > index 86d13d6bc463..30544801d2b8 100644
> > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > @@ -3370,7 +3370,7 @@ int drm_dp_update_payload_part1(struct
> > > drm_dp_mst_topology_mgr *mgr)
> > >         struct drm_dp_payload req_payload;
> > >         struct drm_dp_mst_port *port;
> > >         int i, j;
> > > -       int cur_slots = 1;
> > > +       int cur_slots = mgr->start_slot;
> > >         bool skip;
> > > 
> > >         mutex_lock(&mgr->payload_lock); @@ -4323,7 +4323,7 @@ int
> > > drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
> > >         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
> > > 
> > >         /* max. time slots - one slot for MTP header */
> > > -       if (num_slots > 63)
> > > +       if (num_slots > mgr->total_avail_slots)
> > >                 return -ENOSPC;
> > >         return num_slots;
> > >  }
> > > @@ -4335,7 +4335,7 @@ static int drm_dp_init_vcpi(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >         int ret;
> > > 
> > >         /* max. time slots - one slot for MTP header */
> > > -       if (slots > 63)
> > > +       if (slots > mgr->total_avail_slots)
> > >                 return -ENOSPC;
> > > 
> > >         vcpi->pbn = pbn;
> > > @@ -4509,6 +4509,17 @@ int drm_dp_atomic_release_vcpi_slots(struct
> > > drm_atomic_state *state,
> > >  }
> > >  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
> > > 
> > > +void drm_dp_mst_update_encoding_cap(struct
> > drm_dp_mst_topology_mgr
> > > +*mgr,
> > > uint8_t link_encoding_cap)
> > > +{
> > > +       if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
> > > +               mgr->total_avail_slots = 64;
> > > +               mgr->start_slot = 0;
> > > +       }
> > > +       DRM_DEBUG_KMS("%s encoding format determined\n",
> > > +                     (link_encoding_cap == DP_CAP_ANSI_128B132B) ?
> > > "128b/132b" : "8b/10b");
> > > +}
> > > +EXPORT_SYMBOL(drm_dp_mst_update_encoding_cap);
> > > +
> > 
> > This seems to be missing kdocs, can you fix that?
> > 
> > Also - I'm not convinced this is all of the work we have to do, as there's
> > no
> > locking taking place here in this function. If we're changing the number
> > of
> > available VCPI slots that we have, we need to be able to factor that into
> > the
> > atomic check logic which means that we can't rely on mgr->* for any kind
> > of
> > data that isn't guaranteed to remain consistent throughout the lifetime of
> > the
> > driver or topology. (Note that some of the old MST code didn't follow this
> > logic, so I wouldn't be surprised if there's still exceptions to this we
> > need to
> > clean up).
> > 
> > Note that I still expect we'll have to keep some sort of track of the
> > current
> > total slot count in the topology mgr, but that should be reflecting the
> > currently programmed state and not be relied on from our atomic check.
> > 
> 
> Thanks Lyude for your comments.
> 
> Seems I should keep existing code to keep track of current slot status in
> mgr.
> That information is getting updated each time when topology change detected.
> That slot information saved in mgr is a sort of static, and could only be
> used
> for debug purpose to track what is the current encoding format.

Ahh - in that case maybe we should try getting rid of it (as we could just use
the atomic state for debugging output anyway).

> 
> > IMHO - the correct way we should go about adding support for this is to
> > add
> > something into drm_dp_mst_topology_state and integrate this into the
> > atomic check helpers.
> 
> The slot information should also be added into drm_dp_mst_topology_state to
> reflect the real-time slot status.
> 
> I'd like to confirm the best place to get slot count info. updated.
> Should the update be done within &drm_mode_config_funcs. atomic_check(),
> before new stream is created, OR
> should be updated within drm_dp_mst_atomic_check() ?

drm_dp_mst_atomic_check() would be better, since I imagine that we have to do
this for all drivers using MST
> 
> The updated slot count will be used in drm_dp_mst_atomic_check() to check
> slot limit,
> and in drm_dp_update_payload_part1() as initial cur_slots.
> 
> > 
> > >  /**
> > >   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
> > >   * @mgr: manager for this port
> > > @@ -4540,8 +4551,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > > 
> > >         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
> > >         if (ret) {
> > > -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > > max=63 ret=%d\n",
> > > -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> > > +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > > +max=%d
> > > ret=%d\n",
> > > +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> > > > total_avail_slots, ret);
> > >                 drm_dp_mst_topology_put_port(port);
> > >                 goto out;
> > >         }
> > > @@ -5228,7 +5239,7 @@
> > drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >                                          struct
> > > drm_dp_mst_topology_state
> > > *mst_state)
> > >  {
> > >         struct drm_dp_vcpi_allocation *vcpi;
> > > -       int avail_slots = 63, payload_count = 0;
> > > +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
> > > 
> > >         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
> > >                 /* Releasing VCPI is always OK-even if the port is
> > > gone */ @@ -5257,7 +5268,7 @@
> > > drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >                 }
> > >         }
> > >         drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI
> > > avail=%d used=%d\n",
> > > -                      mgr, mst_state, avail_slots, 63 - avail_slots);
> > > +                      mgr, mst_state, avail_slots,
> > > +mgr->total_avail_slots -
> > > avail_slots);
> > > 
> > >         return 0;
> > >  }
> > > @@ -5529,6 +5540,8 @@ int drm_dp_mst_topology_mgr_init(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >         if (!mgr->proposed_vcpis)
> > >                 return -ENOMEM;
> > >         set_bit(0, &mgr->payload_mask);
> > > +       mgr->total_avail_slots = 63;
> > > +       mgr->start_slot = 1;
> > > 
> > >         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
> > >         if (mst_state == NULL)
> > > diff --git a/include/drm/drm_dp_mst_helper.h
> > > b/include/drm/drm_dp_mst_helper.h index ddb9231d0309..eac5ce48f214
> > > 100644
> > > --- a/include/drm/drm_dp_mst_helper.h
> > > +++ b/include/drm/drm_dp_mst_helper.h
> > > @@ -661,6 +661,15 @@ struct drm_dp_mst_topology_mgr {
> > >          */
> > >         int pbn_div;
> > > 
> > > +       /**
> > > +        * @total_avail_slots: available slots for data transmission
> > > +        */
> > > +       u8 total_avail_slots;
> > > +       /**
> > > +        * @start_slot: first slot index for data transmission
> > > +        */
> > > +       u8 start_slot;
> > > +
> > >         /**
> > >          * @funcs: Atomic helper callbacks
> > >          */
> > 
> > --
> > Cheers,
> >  Lyude Paul (she/her)
> >  Software Engineer at Red Hat
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-08-31 19:44     ` Zuo, Jerry
  2021-08-31 20:19       ` Lyude Paul
@ 2021-08-31 22:44       ` Lyude Paul
  2021-10-12 21:58         ` [PATCH] " Bhawanpreet Lakha
  2021-08-31 22:45       ` [PATCH 1/2] " Lyude Paul
  2 siblings, 1 reply; 37+ messages in thread
From: Lyude Paul @ 2021-08-31 22:44 UTC (permalink / raw)
  To: Zuo, Jerry, dri-devel; +Cc: Wentland, Harry, Kazlauskas, Nicholas, Lin, Wayne

(I am going to try responding to this tomorrow btw. I haven't been super busy
this week, but this has been a surprisingly difficult email to respond to
because I need to actually need to do a deep dive some of the MST helpers
tomorrow to figure out more of the specifics on why I realized we couldn't
just hot add/remove port->connector here).

On Tue, 2021-08-31 at 19:44 +0000, Zuo, Jerry wrote:
> [AMD Official Use Only]
> 
> > -----Original Message-----
> > From: Lyude Paul <lyude@redhat.com>
> > Sent: August 30, 2021 4:00 PM
> > To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org
> > Cc: Wentland, Harry <Harry.Wentland@amd.com>; Kazlauskas, Nicholas
> > <Nicholas.Kazlauskas@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>
> > Subject: Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based
> > on Encoding Format
> > 
> > On Fri, 2021-08-27 at 19:43 -0400, Fangzhi Zuo wrote:
> > > 8b/10b encoding format requires to reserve the first slot for
> > > recording metadata. Real data transmission starts from the second
> > > slot, with a total of available 63 slots available.
> > > 
> > > In 128b/132b encoding format, metadata is transmitted separately in
> > > LLCP packet before MTP. Real data transmission starts from the first
> > > slot, with a total of 64 slots available.
> > > 
> > > Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> > > ---
> > >  drivers/gpu/drm/drm_dp_mst_topology.c | 27
> > > ++++++++++++++++++++-------
> > >  include/drm/drm_dp_mst_helper.h       |  9 +++++++++
> > >  2 files changed, 29 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > index 86d13d6bc463..30544801d2b8 100644
> > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > @@ -3370,7 +3370,7 @@ int drm_dp_update_payload_part1(struct
> > > drm_dp_mst_topology_mgr *mgr)
> > >         struct drm_dp_payload req_payload;
> > >         struct drm_dp_mst_port *port;
> > >         int i, j;
> > > -       int cur_slots = 1;
> > > +       int cur_slots = mgr->start_slot;
> > >         bool skip;
> > > 
> > >         mutex_lock(&mgr->payload_lock); @@ -4323,7 +4323,7 @@ int
> > > drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
> > >         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
> > > 
> > >         /* max. time slots - one slot for MTP header */
> > > -       if (num_slots > 63)
> > > +       if (num_slots > mgr->total_avail_slots)
> > >                 return -ENOSPC;
> > >         return num_slots;
> > >  }
> > > @@ -4335,7 +4335,7 @@ static int drm_dp_init_vcpi(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >         int ret;
> > > 
> > >         /* max. time slots - one slot for MTP header */
> > > -       if (slots > 63)
> > > +       if (slots > mgr->total_avail_slots)
> > >                 return -ENOSPC;
> > > 
> > >         vcpi->pbn = pbn;
> > > @@ -4509,6 +4509,17 @@ int drm_dp_atomic_release_vcpi_slots(struct
> > > drm_atomic_state *state,
> > >  }
> > >  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
> > > 
> > > +void drm_dp_mst_update_encoding_cap(struct
> > drm_dp_mst_topology_mgr
> > > +*mgr,
> > > uint8_t link_encoding_cap)
> > > +{
> > > +       if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
> > > +               mgr->total_avail_slots = 64;
> > > +               mgr->start_slot = 0;
> > > +       }
> > > +       DRM_DEBUG_KMS("%s encoding format determined\n",
> > > +                     (link_encoding_cap == DP_CAP_ANSI_128B132B) ?
> > > "128b/132b" : "8b/10b");
> > > +}
> > > +EXPORT_SYMBOL(drm_dp_mst_update_encoding_cap);
> > > +
> > 
> > This seems to be missing kdocs, can you fix that?
> > 
> > Also - I'm not convinced this is all of the work we have to do, as there's
> > no
> > locking taking place here in this function. If we're changing the number
> > of
> > available VCPI slots that we have, we need to be able to factor that into
> > the
> > atomic check logic which means that we can't rely on mgr->* for any kind
> > of
> > data that isn't guaranteed to remain consistent throughout the lifetime of
> > the
> > driver or topology. (Note that some of the old MST code didn't follow this
> > logic, so I wouldn't be surprised if there's still exceptions to this we
> > need to
> > clean up).
> > 
> > Note that I still expect we'll have to keep some sort of track of the
> > current
> > total slot count in the topology mgr, but that should be reflecting the
> > currently programmed state and not be relied on from our atomic check.
> > 
> 
> Thanks Lyude for your comments.
> 
> Seems I should keep existing code to keep track of current slot status in
> mgr.
> That information is getting updated each time when topology change detected.
> That slot information saved in mgr is a sort of static, and could only be
> used
> for debug purpose to track what is the current encoding format.
> 
> > IMHO - the correct way we should go about adding support for this is to
> > add
> > something into drm_dp_mst_topology_state and integrate this into the
> > atomic check helpers.
> 
> The slot information should also be added into drm_dp_mst_topology_state to
> reflect the real-time slot status.
> 
> I'd like to confirm the best place to get slot count info. updated.
> Should the update be done within &drm_mode_config_funcs. atomic_check(),
> before new stream is created, OR
> should be updated within drm_dp_mst_atomic_check() ?
> 
> The updated slot count will be used in drm_dp_mst_atomic_check() to check
> slot limit,
> and in drm_dp_update_payload_part1() as initial cur_slots.
> 
> > 
> > >  /**
> > >   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
> > >   * @mgr: manager for this port
> > > @@ -4540,8 +4551,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > > 
> > >         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
> > >         if (ret) {
> > > -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > > max=63 ret=%d\n",
> > > -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> > > +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > > +max=%d
> > > ret=%d\n",
> > > +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> > > > total_avail_slots, ret);
> > >                 drm_dp_mst_topology_put_port(port);
> > >                 goto out;
> > >         }
> > > @@ -5228,7 +5239,7 @@
> > drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >                                          struct
> > > drm_dp_mst_topology_state
> > > *mst_state)
> > >  {
> > >         struct drm_dp_vcpi_allocation *vcpi;
> > > -       int avail_slots = 63, payload_count = 0;
> > > +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
> > > 
> > >         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
> > >                 /* Releasing VCPI is always OK-even if the port is
> > > gone */ @@ -5257,7 +5268,7 @@
> > > drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >                 }
> > >         }
> > >         drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI
> > > avail=%d used=%d\n",
> > > -                      mgr, mst_state, avail_slots, 63 - avail_slots);
> > > +                      mgr, mst_state, avail_slots,
> > > +mgr->total_avail_slots -
> > > avail_slots);
> > > 
> > >         return 0;
> > >  }
> > > @@ -5529,6 +5540,8 @@ int drm_dp_mst_topology_mgr_init(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >         if (!mgr->proposed_vcpis)
> > >                 return -ENOMEM;
> > >         set_bit(0, &mgr->payload_mask);
> > > +       mgr->total_avail_slots = 63;
> > > +       mgr->start_slot = 1;
> > > 
> > >         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
> > >         if (mst_state == NULL)
> > > diff --git a/include/drm/drm_dp_mst_helper.h
> > > b/include/drm/drm_dp_mst_helper.h index ddb9231d0309..eac5ce48f214
> > > 100644
> > > --- a/include/drm/drm_dp_mst_helper.h
> > > +++ b/include/drm/drm_dp_mst_helper.h
> > > @@ -661,6 +661,15 @@ struct drm_dp_mst_topology_mgr {
> > >          */
> > >         int pbn_div;
> > > 
> > > +       /**
> > > +        * @total_avail_slots: available slots for data transmission
> > > +        */
> > > +       u8 total_avail_slots;
> > > +       /**
> > > +        * @start_slot: first slot index for data transmission
> > > +        */
> > > +       u8 start_slot;
> > > +
> > >         /**
> > >          * @funcs: Atomic helper callbacks
> > >          */
> > 
> > --
> > Cheers,
> >  Lyude Paul (she/her)
> >  Software Engineer at Red Hat
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-08-31 19:44     ` Zuo, Jerry
  2021-08-31 20:19       ` Lyude Paul
  2021-08-31 22:44       ` Lyude Paul
@ 2021-08-31 22:45       ` Lyude Paul
  2021-08-31 22:46         ` Lyude Paul
  2 siblings, 1 reply; 37+ messages in thread
From: Lyude Paul @ 2021-08-31 22:45 UTC (permalink / raw)
  To: Zuo, Jerry, dri-devel; +Cc: Wentland, Harry, Kazlauskas, Nicholas, Lin, Wayne

(sorry - I just wrote a second response to your email I meant to send to your
coworker Jerry Zuo! You can ignore it)

On Tue, 2021-08-31 at 19:44 +0000, Zuo, Jerry wrote:
> [AMD Official Use Only]
> 
> > -----Original Message-----
> > From: Lyude Paul <lyude@redhat.com>
> > Sent: August 30, 2021 4:00 PM
> > To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org
> > Cc: Wentland, Harry <Harry.Wentland@amd.com>; Kazlauskas, Nicholas
> > <Nicholas.Kazlauskas@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>
> > Subject: Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based
> > on Encoding Format
> > 
> > On Fri, 2021-08-27 at 19:43 -0400, Fangzhi Zuo wrote:
> > > 8b/10b encoding format requires to reserve the first slot for
> > > recording metadata. Real data transmission starts from the second
> > > slot, with a total of available 63 slots available.
> > > 
> > > In 128b/132b encoding format, metadata is transmitted separately in
> > > LLCP packet before MTP. Real data transmission starts from the first
> > > slot, with a total of 64 slots available.
> > > 
> > > Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> > > ---
> > >  drivers/gpu/drm/drm_dp_mst_topology.c | 27
> > > ++++++++++++++++++++-------
> > >  include/drm/drm_dp_mst_helper.h       |  9 +++++++++
> > >  2 files changed, 29 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > index 86d13d6bc463..30544801d2b8 100644
> > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > @@ -3370,7 +3370,7 @@ int drm_dp_update_payload_part1(struct
> > > drm_dp_mst_topology_mgr *mgr)
> > >         struct drm_dp_payload req_payload;
> > >         struct drm_dp_mst_port *port;
> > >         int i, j;
> > > -       int cur_slots = 1;
> > > +       int cur_slots = mgr->start_slot;
> > >         bool skip;
> > > 
> > >         mutex_lock(&mgr->payload_lock); @@ -4323,7 +4323,7 @@ int
> > > drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
> > >         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
> > > 
> > >         /* max. time slots - one slot for MTP header */
> > > -       if (num_slots > 63)
> > > +       if (num_slots > mgr->total_avail_slots)
> > >                 return -ENOSPC;
> > >         return num_slots;
> > >  }
> > > @@ -4335,7 +4335,7 @@ static int drm_dp_init_vcpi(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >         int ret;
> > > 
> > >         /* max. time slots - one slot for MTP header */
> > > -       if (slots > 63)
> > > +       if (slots > mgr->total_avail_slots)
> > >                 return -ENOSPC;
> > > 
> > >         vcpi->pbn = pbn;
> > > @@ -4509,6 +4509,17 @@ int drm_dp_atomic_release_vcpi_slots(struct
> > > drm_atomic_state *state,
> > >  }
> > >  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
> > > 
> > > +void drm_dp_mst_update_encoding_cap(struct
> > drm_dp_mst_topology_mgr
> > > +*mgr,
> > > uint8_t link_encoding_cap)
> > > +{
> > > +       if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
> > > +               mgr->total_avail_slots = 64;
> > > +               mgr->start_slot = 0;
> > > +       }
> > > +       DRM_DEBUG_KMS("%s encoding format determined\n",
> > > +                     (link_encoding_cap == DP_CAP_ANSI_128B132B) ?
> > > "128b/132b" : "8b/10b");
> > > +}
> > > +EXPORT_SYMBOL(drm_dp_mst_update_encoding_cap);
> > > +
> > 
> > This seems to be missing kdocs, can you fix that?
> > 
> > Also - I'm not convinced this is all of the work we have to do, as there's
> > no
> > locking taking place here in this function. If we're changing the number
> > of
> > available VCPI slots that we have, we need to be able to factor that into
> > the
> > atomic check logic which means that we can't rely on mgr->* for any kind
> > of
> > data that isn't guaranteed to remain consistent throughout the lifetime of
> > the
> > driver or topology. (Note that some of the old MST code didn't follow this
> > logic, so I wouldn't be surprised if there's still exceptions to this we
> > need to
> > clean up).
> > 
> > Note that I still expect we'll have to keep some sort of track of the
> > current
> > total slot count in the topology mgr, but that should be reflecting the
> > currently programmed state and not be relied on from our atomic check.
> > 
> 
> Thanks Lyude for your comments.
> 
> Seems I should keep existing code to keep track of current slot status in
> mgr.
> That information is getting updated each time when topology change detected.
> That slot information saved in mgr is a sort of static, and could only be
> used
> for debug purpose to track what is the current encoding format.
> 
> > IMHO - the correct way we should go about adding support for this is to
> > add
> > something into drm_dp_mst_topology_state and integrate this into the
> > atomic check helpers.
> 
> The slot information should also be added into drm_dp_mst_topology_state to
> reflect the real-time slot status.
> 
> I'd like to confirm the best place to get slot count info. updated.
> Should the update be done within &drm_mode_config_funcs. atomic_check(),
> before new stream is created, OR
> should be updated within drm_dp_mst_atomic_check() ?
> 
> The updated slot count will be used in drm_dp_mst_atomic_check() to check
> slot limit,
> and in drm_dp_update_payload_part1() as initial cur_slots.
> 
> > 
> > >  /**
> > >   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
> > >   * @mgr: manager for this port
> > > @@ -4540,8 +4551,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > > 
> > >         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
> > >         if (ret) {
> > > -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > > max=63 ret=%d\n",
> > > -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> > > +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > > +max=%d
> > > ret=%d\n",
> > > +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> > > > total_avail_slots, ret);
> > >                 drm_dp_mst_topology_put_port(port);
> > >                 goto out;
> > >         }
> > > @@ -5228,7 +5239,7 @@
> > drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >                                          struct
> > > drm_dp_mst_topology_state
> > > *mst_state)
> > >  {
> > >         struct drm_dp_vcpi_allocation *vcpi;
> > > -       int avail_slots = 63, payload_count = 0;
> > > +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
> > > 
> > >         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
> > >                 /* Releasing VCPI is always OK-even if the port is
> > > gone */ @@ -5257,7 +5268,7 @@
> > > drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >                 }
> > >         }
> > >         drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI
> > > avail=%d used=%d\n",
> > > -                      mgr, mst_state, avail_slots, 63 - avail_slots);
> > > +                      mgr, mst_state, avail_slots,
> > > +mgr->total_avail_slots -
> > > avail_slots);
> > > 
> > >         return 0;
> > >  }
> > > @@ -5529,6 +5540,8 @@ int drm_dp_mst_topology_mgr_init(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >         if (!mgr->proposed_vcpis)
> > >                 return -ENOMEM;
> > >         set_bit(0, &mgr->payload_mask);
> > > +       mgr->total_avail_slots = 63;
> > > +       mgr->start_slot = 1;
> > > 
> > >         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
> > >         if (mst_state == NULL)
> > > diff --git a/include/drm/drm_dp_mst_helper.h
> > > b/include/drm/drm_dp_mst_helper.h index ddb9231d0309..eac5ce48f214
> > > 100644
> > > --- a/include/drm/drm_dp_mst_helper.h
> > > +++ b/include/drm/drm_dp_mst_helper.h
> > > @@ -661,6 +661,15 @@ struct drm_dp_mst_topology_mgr {
> > >          */
> > >         int pbn_div;
> > > 
> > > +       /**
> > > +        * @total_avail_slots: available slots for data transmission
> > > +        */
> > > +       u8 total_avail_slots;
> > > +       /**
> > > +        * @start_slot: first slot index for data transmission
> > > +        */
> > > +       u8 start_slot;
> > > +
> > >         /**
> > >          * @funcs: Atomic helper callbacks
> > >          */
> > 
> > --
> > Cheers,
> >  Lyude Paul (she/her)
> >  Software Engineer at Red Hat
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-08-31 22:45       ` [PATCH 1/2] " Lyude Paul
@ 2021-08-31 22:46         ` Lyude Paul
  0 siblings, 0 replies; 37+ messages in thread
From: Lyude Paul @ 2021-08-31 22:46 UTC (permalink / raw)
  To: Zuo, Jerry, dri-devel; +Cc: Wentland, Harry, Kazlauskas, Nicholas, Lin, Wayne

...I meant Wayne Lin, whoops. been going through a lot of emails today 😅


On Tue, 2021-08-31 at 18:45 -0400, Lyude Paul wrote:
> (sorry - I just wrote a second response to your email I meant to send to
> your
> coworker Jerry Zuo! You can ignore it)
> 
> On Tue, 2021-08-31 at 19:44 +0000, Zuo, Jerry wrote:
> > [AMD Official Use Only]
> > 
> > > -----Original Message-----
> > > From: Lyude Paul <lyude@redhat.com>
> > > Sent: August 30, 2021 4:00 PM
> > > To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org
> > > Cc: Wentland, Harry <Harry.Wentland@amd.com>; Kazlauskas, Nicholas
> > > <Nicholas.Kazlauskas@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>
> > > Subject: Re: [PATCH 1/2] drm: Update MST First Link Slot Information
> > > Based
> > > on Encoding Format
> > > 
> > > On Fri, 2021-08-27 at 19:43 -0400, Fangzhi Zuo wrote:
> > > > 8b/10b encoding format requires to reserve the first slot for
> > > > recording metadata. Real data transmission starts from the second
> > > > slot, with a total of available 63 slots available.
> > > > 
> > > > In 128b/132b encoding format, metadata is transmitted separately in
> > > > LLCP packet before MTP. Real data transmission starts from the first
> > > > slot, with a total of 64 slots available.
> > > > 
> > > > Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> > > > ---
> > > >  drivers/gpu/drm/drm_dp_mst_topology.c | 27
> > > > ++++++++++++++++++++-------
> > > >  include/drm/drm_dp_mst_helper.h       |  9 +++++++++
> > > >  2 files changed, 29 insertions(+), 7 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > index 86d13d6bc463..30544801d2b8 100644
> > > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > @@ -3370,7 +3370,7 @@ int drm_dp_update_payload_part1(struct
> > > > drm_dp_mst_topology_mgr *mgr)
> > > >         struct drm_dp_payload req_payload;
> > > >         struct drm_dp_mst_port *port;
> > > >         int i, j;
> > > > -       int cur_slots = 1;
> > > > +       int cur_slots = mgr->start_slot;
> > > >         bool skip;
> > > > 
> > > >         mutex_lock(&mgr->payload_lock); @@ -4323,7 +4323,7 @@ int
> > > > drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
> > > >         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
> > > > 
> > > >         /* max. time slots - one slot for MTP header */
> > > > -       if (num_slots > 63)
> > > > +       if (num_slots > mgr->total_avail_slots)
> > > >                 return -ENOSPC;
> > > >         return num_slots;
> > > >  }
> > > > @@ -4335,7 +4335,7 @@ static int drm_dp_init_vcpi(struct
> > > > drm_dp_mst_topology_mgr *mgr,
> > > >         int ret;
> > > > 
> > > >         /* max. time slots - one slot for MTP header */
> > > > -       if (slots > 63)
> > > > +       if (slots > mgr->total_avail_slots)
> > > >                 return -ENOSPC;
> > > > 
> > > >         vcpi->pbn = pbn;
> > > > @@ -4509,6 +4509,17 @@ int drm_dp_atomic_release_vcpi_slots(struct
> > > > drm_atomic_state *state,
> > > >  }
> > > >  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
> > > > 
> > > > +void drm_dp_mst_update_encoding_cap(struct
> > > drm_dp_mst_topology_mgr
> > > > +*mgr,
> > > > uint8_t link_encoding_cap)
> > > > +{
> > > > +       if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
> > > > +               mgr->total_avail_slots = 64;
> > > > +               mgr->start_slot = 0;
> > > > +       }
> > > > +       DRM_DEBUG_KMS("%s encoding format determined\n",
> > > > +                     (link_encoding_cap == DP_CAP_ANSI_128B132B) ?
> > > > "128b/132b" : "8b/10b");
> > > > +}
> > > > +EXPORT_SYMBOL(drm_dp_mst_update_encoding_cap);
> > > > +
> > > 
> > > This seems to be missing kdocs, can you fix that?
> > > 
> > > Also - I'm not convinced this is all of the work we have to do, as
> > > there's
> > > no
> > > locking taking place here in this function. If we're changing the number
> > > of
> > > available VCPI slots that we have, we need to be able to factor that
> > > into
> > > the
> > > atomic check logic which means that we can't rely on mgr->* for any kind
> > > of
> > > data that isn't guaranteed to remain consistent throughout the lifetime
> > > of
> > > the
> > > driver or topology. (Note that some of the old MST code didn't follow
> > > this
> > > logic, so I wouldn't be surprised if there's still exceptions to this we
> > > need to
> > > clean up).
> > > 
> > > Note that I still expect we'll have to keep some sort of track of the
> > > current
> > > total slot count in the topology mgr, but that should be reflecting the
> > > currently programmed state and not be relied on from our atomic check.
> > > 
> > 
> > Thanks Lyude for your comments.
> > 
> > Seems I should keep existing code to keep track of current slot status in
> > mgr.
> > That information is getting updated each time when topology change
> > detected.
> > That slot information saved in mgr is a sort of static, and could only be
> > used
> > for debug purpose to track what is the current encoding format.
> > 
> > > IMHO - the correct way we should go about adding support for this is to
> > > add
> > > something into drm_dp_mst_topology_state and integrate this into the
> > > atomic check helpers.
> > 
> > The slot information should also be added into drm_dp_mst_topology_state
> > to
> > reflect the real-time slot status.
> > 
> > I'd like to confirm the best place to get slot count info. updated.
> > Should the update be done within &drm_mode_config_funcs. atomic_check(),
> > before new stream is created, OR
> > should be updated within drm_dp_mst_atomic_check() ?
> > 
> > The updated slot count will be used in drm_dp_mst_atomic_check() to check
> > slot limit,
> > and in drm_dp_update_payload_part1() as initial cur_slots.
> > 
> > > 
> > > >  /**
> > > >   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
> > > >   * @mgr: manager for this port
> > > > @@ -4540,8 +4551,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> > > > drm_dp_mst_topology_mgr *mgr,
> > > > 
> > > >         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
> > > >         if (ret) {
> > > > -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > > > max=63 ret=%d\n",
> > > > -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> > > > +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > > > +max=%d
> > > > ret=%d\n",
> > > > +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> > > > > total_avail_slots, ret);
> > > >                 drm_dp_mst_topology_put_port(port);
> > > >                 goto out;
> > > >         }
> > > > @@ -5228,7 +5239,7 @@
> > > drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > > > drm_dp_mst_topology_mgr *mgr,
> > > >                                          struct
> > > > drm_dp_mst_topology_state
> > > > *mst_state)
> > > >  {
> > > >         struct drm_dp_vcpi_allocation *vcpi;
> > > > -       int avail_slots = 63, payload_count = 0;
> > > > +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
> > > > 
> > > >         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
> > > >                 /* Releasing VCPI is always OK-even if the port is
> > > > gone */ @@ -5257,7 +5268,7 @@
> > > > drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > > > drm_dp_mst_topology_mgr *mgr,
> > > >                 }
> > > >         }
> > > >         drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI
> > > > avail=%d used=%d\n",
> > > > -                      mgr, mst_state, avail_slots, 63 - avail_slots);
> > > > +                      mgr, mst_state, avail_slots,
> > > > +mgr->total_avail_slots -
> > > > avail_slots);
> > > > 
> > > >         return 0;
> > > >  }
> > > > @@ -5529,6 +5540,8 @@ int drm_dp_mst_topology_mgr_init(struct
> > > > drm_dp_mst_topology_mgr *mgr,
> > > >         if (!mgr->proposed_vcpis)
> > > >                 return -ENOMEM;
> > > >         set_bit(0, &mgr->payload_mask);
> > > > +       mgr->total_avail_slots = 63;
> > > > +       mgr->start_slot = 1;
> > > > 
> > > >         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
> > > >         if (mst_state == NULL)
> > > > diff --git a/include/drm/drm_dp_mst_helper.h
> > > > b/include/drm/drm_dp_mst_helper.h index ddb9231d0309..eac5ce48f214
> > > > 100644
> > > > --- a/include/drm/drm_dp_mst_helper.h
> > > > +++ b/include/drm/drm_dp_mst_helper.h
> > > > @@ -661,6 +661,15 @@ struct drm_dp_mst_topology_mgr {
> > > >          */
> > > >         int pbn_div;
> > > > 
> > > > +       /**
> > > > +        * @total_avail_slots: available slots for data transmission
> > > > +        */
> > > > +       u8 total_avail_slots;
> > > > +       /**
> > > > +        * @start_slot: first slot index for data transmission
> > > > +        */
> > > > +       u8 start_slot;
> > > > +
> > > >         /**
> > > >          * @funcs: Atomic helper callbacks
> > > >          */
> > > 
> > > --
> > > Cheers,
> > >  Lyude Paul (she/her)
> > >  Software Engineer at Red Hat
> > 
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-08-31 22:44       ` Lyude Paul
@ 2021-10-12 21:58         ` Bhawanpreet Lakha
  2021-10-12 22:02           ` Lakha, Bhawanpreet
                             ` (4 more replies)
  0 siblings, 5 replies; 37+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-12 21:58 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Bhawanpreet Lakha

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

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

v2:
* Remove get_mst_link_encoding_cap
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++++++
 drivers/gpu/drm/drm_dp_mst_topology.c         | 35 +++++++++++++++----
 include/drm/drm_dp_mst_helper.h               | 13 +++++++
 3 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 5020f2d36fe1..4ad50eb0091a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10612,6 +10612,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	struct dsc_mst_fairness_vars vars[MAX_PIPES];
 #endif
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_topology_mgr *mgr;
 
 	trace_amdgpu_dm_atomic_check_begin(state);
 
@@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 		lock_and_validation_needed = true;
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
+		struct amdgpu_dm_connector *aconnector;
+		struct drm_connector *connector;
+		struct drm_connector_list_iter iter;
+		u8 link_coding_cap;
+
+		if (!mgr->mst_state )
+			continue;
+
+		drm_connector_list_iter_begin(dev, &iter);
+		drm_for_each_connector_iter(connector, &iter) {
+			int id = connector->index;
+
+			if (id == mst_state->mgr->conn_base_id) {
+				aconnector = to_amdgpu_dm_connector(connector);
+				link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
+				drm_dp_mst_update_coding_cap(mst_state, link_coding_cap);
+
+				break;
+			}
+		}
+		drm_connector_list_iter_end(&iter);
+
+	}
+#endif
 	/**
 	 * Streams and planes are reset when there are changes that affect
 	 * bandwidth. Anything that affects bandwidth needs to go through
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index ad0795afc21c..fb5c47c4cb2e 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
 	struct drm_dp_payload req_payload;
 	struct drm_dp_mst_port *port;
 	int i, j;
-	int cur_slots = 1;
+	int cur_slots = mgr->start_slot;
 	bool skip;
 
 	mutex_lock(&mgr->payload_lock);
@@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
 	num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
 
 	/* max. time slots - one slot for MTP header */
-	if (num_slots > 63)
+	if (num_slots > mgr->total_avail_slots)
 		return -ENOSPC;
 	return num_slots;
 }
@@ -4333,7 +4333,7 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 	int ret;
 
 	/* max. time slots - one slot for MTP header */
-	if (slots > 63)
+	if (slots > mgr->total_avail_slots)
 		return -ENOSPC;
 
 	vcpi->pbn = pbn;
@@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 
+void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state *mst_state, uint8_t link_coding_cap)
+{
+	if (link_coding_cap == DP_CAP_ANSI_128B132B) {
+		mst_state->total_avail_slots = 64;
+		mst_state->start_slot = 0;
+	}
+
+	DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
+			(link_coding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b", mst_state->mgr);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 
 	ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
 	if (ret) {
-		drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63 ret=%d\n",
-			    DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
+		drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=%d ret=%d\n",
+			    DIV_ROUND_UP(pbn, mgr->pbn_div), mgr->total_avail_slots, ret);
 		drm_dp_mst_topology_put_port(port);
 		goto out;
 	}
@@ -5226,7 +5238,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 					 struct drm_dp_mst_topology_state *mst_state)
 {
 	struct drm_dp_vcpi_allocation *vcpi;
-	int avail_slots = 63, payload_count = 0;
+	int avail_slots = mgr->total_avail_slots, payload_count = 0;
 
 	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
 		/* Releasing VCPI is always OK-even if the port is gone */
@@ -5255,7 +5267,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 		}
 	}
 	drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
-		       mgr, mst_state, avail_slots, 63 - avail_slots);
+		       mgr, mst_state, avail_slots, mgr->total_avail_slots - avail_slots);
 
 	return 0;
 }
@@ -5421,6 +5433,10 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state *state)
 			break;
 
 		mutex_lock(&mgr->lock);
+
+		mgr->start_slot = mst_state->start_slot;
+		mgr->total_avail_slots = mst_state->total_avail_slots;
+
 		ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,
 							    mst_state);
 		mutex_unlock(&mgr->lock);
@@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	if (!mgr->proposed_vcpis)
 		return -ENOMEM;
 	set_bit(0, &mgr->payload_mask);
+	mgr->total_avail_slots = 63;
+	mgr->start_slot = 1;
 
 	mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
 	if (mst_state == NULL)
 		return -ENOMEM;
 
+	mst_state->total_avail_slots = 63;
+	mst_state->start_slot = 1;
+
 	mst_state->mgr = mgr;
 	INIT_LIST_HEAD(&mst_state->vcpis);
 
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index ddb9231d0309..f8152dfb34ed 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
 	struct drm_private_state base;
 	struct list_head vcpis;
 	struct drm_dp_mst_topology_mgr *mgr;
+	u8 total_avail_slots;
+	u8 start_slot;
 };
 
 #define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
@@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
 	 */
 	int pbn_div;
 
+	/**
+	 * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
+	 */
+	u8 total_avail_slots;
+
+	/**
+	 * @start_slot: 1 for 8b/10b, 0 for 128/132b
+	 */
+	u8 start_slot;
+
 	/**
 	 * @funcs: Atomic helper callbacks
 	 */
@@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
 
 void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
+void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state *mst_state, uint8_t link_coding_cap);
 
 void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 				struct drm_dp_mst_port *port);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-12 21:58         ` [PATCH] " Bhawanpreet Lakha
@ 2021-10-12 22:02           ` Lakha, Bhawanpreet
  2021-10-12 22:09             ` Lyude Paul
  2021-10-13 16:09           ` Jani Nikula
                             ` (3 subsequent siblings)
  4 siblings, 1 reply; 37+ messages in thread
From: Lakha, Bhawanpreet @ 2021-10-12 22:02 UTC (permalink / raw)
  To: Zuo, Jerry, dri-devel, lyude
  Cc: Wentland, Harry, Lin, Wayne, Kazlauskas, Nicholas

[-- Attachment #1: Type: text/plain, Size: 9683 bytes --]

[AMD Official Use Only]


Hi Lyude,

Jerry is busy these few weeks so I will be taking a look at this. I added the start/total slots to the mst_state and am updating them in atomic_check.

Also ignore the V2 "* Remove get_mst_link_encoding_cap" I got a bit lost in trying to figure out the patch layout that was sent before.


Thanks,
Bhawan

________________________________
From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Sent: October 12, 2021 5:58 PM
To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org <dri-devel@lists.freedesktop.org>; lyude@redhat.com <lyude@redhat.com>
Cc: Wentland, Harry <Harry.Wentland@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>; Kazlauskas, Nicholas <Nicholas.Kazlauskas@amd.com>; Lakha, Bhawanpreet <Bhawanpreet.Lakha@amd.com>
Subject: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format

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

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

v2:
* Remove get_mst_link_encoding_cap
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++++++
 drivers/gpu/drm/drm_dp_mst_topology.c         | 35 +++++++++++++++----
 include/drm/drm_dp_mst_helper.h               | 13 +++++++
 3 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 5020f2d36fe1..4ad50eb0091a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10612,6 +10612,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 #if defined(CONFIG_DRM_AMD_DC_DCN)
         struct dsc_mst_fairness_vars vars[MAX_PIPES];
 #endif
+       struct drm_dp_mst_topology_state *mst_state;
+       struct drm_dp_mst_topology_mgr *mgr;

         trace_amdgpu_dm_atomic_check_begin(state);

@@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                 lock_and_validation_needed = true;
         }

+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
+               struct amdgpu_dm_connector *aconnector;
+               struct drm_connector *connector;
+               struct drm_connector_list_iter iter;
+               u8 link_coding_cap;
+
+               if (!mgr->mst_state )
+                       continue;
+
+               drm_connector_list_iter_begin(dev, &iter);
+               drm_for_each_connector_iter(connector, &iter) {
+                       int id = connector->index;
+
+                       if (id == mst_state->mgr->conn_base_id) {
+                               aconnector = to_amdgpu_dm_connector(connector);
+                               link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
+                               drm_dp_mst_update_coding_cap(mst_state, link_coding_cap);
+
+                               break;
+                       }
+               }
+               drm_connector_list_iter_end(&iter);
+
+       }
+#endif
         /**
          * Streams and planes are reset when there are changes that affect
          * bandwidth. Anything that affects bandwidth needs to go through
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index ad0795afc21c..fb5c47c4cb2e 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
         struct drm_dp_payload req_payload;
         struct drm_dp_mst_port *port;
         int i, j;
-       int cur_slots = 1;
+       int cur_slots = mgr->start_slot;
         bool skip;

         mutex_lock(&mgr->payload_lock);
@@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);

         /* max. time slots - one slot for MTP header */
-       if (num_slots > 63)
+       if (num_slots > mgr->total_avail_slots)
                 return -ENOSPC;
         return num_slots;
 }
@@ -4333,7 +4333,7 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
         int ret;

         /* max. time slots - one slot for MTP header */
-       if (slots > 63)
+       if (slots > mgr->total_avail_slots)
                 return -ENOSPC;

         vcpi->pbn = pbn;
@@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);

+void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state *mst_state, uint8_t link_coding_cap)
+{
+       if (link_coding_cap == DP_CAP_ANSI_128B132B) {
+               mst_state->total_avail_slots = 64;
+               mst_state->start_slot = 0;
+       }
+
+       DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
+                       (link_coding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b", mst_state->mgr);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,

         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
         if (ret) {
-               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63 ret=%d\n",
-                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
+               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=%d ret=%d\n",
+                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr->total_avail_slots, ret);
                 drm_dp_mst_topology_put_port(port);
                 goto out;
         }
@@ -5226,7 +5238,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
                                          struct drm_dp_mst_topology_state *mst_state)
 {
         struct drm_dp_vcpi_allocation *vcpi;
-       int avail_slots = 63, payload_count = 0;
+       int avail_slots = mgr->total_avail_slots, payload_count = 0;

         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
                 /* Releasing VCPI is always OK-even if the port is gone */
@@ -5255,7 +5267,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
                 }
         }
         drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
-                      mgr, mst_state, avail_slots, 63 - avail_slots);
+                      mgr, mst_state, avail_slots, mgr->total_avail_slots - avail_slots);

         return 0;
 }
@@ -5421,6 +5433,10 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state *state)
                         break;

                 mutex_lock(&mgr->lock);
+
+               mgr->start_slot = mst_state->start_slot;
+               mgr->total_avail_slots = mst_state->total_avail_slots;
+
                 ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,
                                                             mst_state);
                 mutex_unlock(&mgr->lock);
@@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
         if (!mgr->proposed_vcpis)
                 return -ENOMEM;
         set_bit(0, &mgr->payload_mask);
+       mgr->total_avail_slots = 63;
+       mgr->start_slot = 1;

         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
         if (mst_state == NULL)
                 return -ENOMEM;

+       mst_state->total_avail_slots = 63;
+       mst_state->start_slot = 1;
+
         mst_state->mgr = mgr;
         INIT_LIST_HEAD(&mst_state->vcpis);

diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index ddb9231d0309..f8152dfb34ed 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
         struct drm_private_state base;
         struct list_head vcpis;
         struct drm_dp_mst_topology_mgr *mgr;
+       u8 total_avail_slots;
+       u8 start_slot;
 };

 #define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
@@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
          */
         int pbn_div;

+       /**
+        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
+        */
+       u8 total_avail_slots;
+
+       /**
+        * @start_slot: 1 for 8b/10b, 0 for 128/132b
+        */
+       u8 start_slot;
+
         /**
          * @funcs: Atomic helper callbacks
          */
@@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp

 void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);

+void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state *mst_state, uint8_t link_coding_cap);

 void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
                                 struct drm_dp_mst_port *port);
--
2.25.1


[-- Attachment #2: Type: text/html, Size: 18965 bytes --]

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-12 22:02           ` Lakha, Bhawanpreet
@ 2021-10-12 22:09             ` Lyude Paul
  0 siblings, 0 replies; 37+ messages in thread
From: Lyude Paul @ 2021-10-12 22:09 UTC (permalink / raw)
  To: Lakha, Bhawanpreet, Zuo, Jerry, dri-devel
  Cc: Wentland, Harry, Lin, Wayne, Kazlauskas, Nicholas

[-- Attachment #1: Type: text/plain, Size: 11590 bytes --]

No problem, thanks for the patches! Will take a look at this tomorrow

On Tue, 2021-10-12 at 22:02 +0000, Lakha, Bhawanpreet wrote:
> [AMD Official Use Only]
> 
> Hi Lyude,
> 
> Jerry is busy these few weeks so I will be taking a look at this. I added
> the start/total slots to the mst_state and am updating them in atomic_check.
> 
> Also ignore the V2 "* Remove get_mst_link_encoding_cap" I got a bit lost in
> trying to figure out the patch layout that was sent before.
> 
> 
> Thanks,
> Bhawan
> 
> From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> Sent: October 12, 2021 5:58 PM
> To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org <dri-
> devel@lists.freedesktop.org>; lyude@redhat.com <lyude@redhat.com>
> Cc: Wentland, Harry <Harry.Wentland@amd.com>; Lin, Wayne
> <Wayne.Lin@amd.com>; Kazlauskas, Nicholas <Nicholas.Kazlauskas@amd.com>;
> Lakha, Bhawanpreet <Bhawanpreet.Lakha@amd.com>
> Subject: [PATCH] drm: Update MST First Link Slot Information Based on
> Encoding Format 
> 8b/10b encoding format requires to reserve the first slot for
> recording metadata. Real data transmission starts from the second slot,
> with a total of available 63 slots available.
> 
> In 128b/132b encoding format, metadata is transmitted separately
> in LLCP packet before MTP. Real data transmission starts from
> the first slot, with a total of 64 slots available.
> 
> v2:
> * Remove get_mst_link_encoding_cap
> * Move total/start slots to mst_state, and copy it to mst_mgr in
> atomic_check
> 
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++++++
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 35 +++++++++++++++----
>  include/drm/drm_dp_mst_helper.h               | 13 +++++++
>  3 files changed, 69 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 5020f2d36fe1..4ad50eb0091a 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -10612,6 +10612,8 @@ static int amdgpu_dm_atomic_check(struct drm_device
> *dev,
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
>          struct dsc_mst_fairness_vars vars[MAX_PIPES];
>  #endif
> +       struct drm_dp_mst_topology_state *mst_state;
> +       struct drm_dp_mst_topology_mgr *mgr;
>  
>          trace_amdgpu_dm_atomic_check_begin(state);
>  
> @@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device
> *dev,
>                  lock_and_validation_needed = true;
>          }
>  
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
> +               struct amdgpu_dm_connector *aconnector;
> +               struct drm_connector *connector;
> +               struct drm_connector_list_iter iter;
> +               u8 link_coding_cap;
> +
> +               if (!mgr->mst_state )
> +                       continue;
> +
> +               drm_connector_list_iter_begin(dev, &iter);
> +               drm_for_each_connector_iter(connector, &iter) {
> +                       int id = connector->index;
> +
> +                       if (id == mst_state->mgr->conn_base_id) {
> +                               aconnector =
> to_amdgpu_dm_connector(connector);
> +                               link_coding_cap =
> dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
> +                               drm_dp_mst_update_coding_cap(mst_state,
> link_coding_cap);
> +
> +                               break;
> +                       }
> +               }
> +               drm_connector_list_iter_end(&iter);
> +
> +       }
> +#endif
>          /**
>           * Streams and planes are reset when there are changes that affect
>           * bandwidth. Anything that affects bandwidth needs to go through
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index ad0795afc21c..fb5c47c4cb2e 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct
> drm_dp_mst_topology_mgr *mgr)
>          struct drm_dp_payload req_payload;
>          struct drm_dp_mst_port *port;
>          int i, j;
> -       int cur_slots = 1;
> +       int cur_slots = mgr->start_slot;
>          bool skip;
>  
>          mutex_lock(&mgr->payload_lock);
> @@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct
> drm_dp_mst_topology_mgr *mgr,
>          num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
>  
>          /* max. time slots - one slot for MTP header */
> -       if (num_slots > 63)
> +       if (num_slots > mgr->total_avail_slots)
>                  return -ENOSPC;
>          return num_slots;
>  }
> @@ -4333,7 +4333,7 @@ static int drm_dp_init_vcpi(struct
> drm_dp_mst_topology_mgr *mgr,
>          int ret;
>  
>          /* max. time slots - one slot for MTP header */
> -       if (slots > 63)
> +       if (slots > mgr->total_avail_slots)
>                  return -ENOSPC;
>  
>          vcpi->pbn = pbn;
> @@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct
> drm_atomic_state *state,
>  }
>  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>  
> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
> *mst_state, uint8_t link_coding_cap)
> +{
> +       if (link_coding_cap == DP_CAP_ANSI_128B132B) {
> +               mst_state->total_avail_slots = 64;
> +               mst_state->start_slot = 0;
> +       }
> +
> +       DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
> +                       (link_coding_cap == DP_CAP_ANSI_128B132B) ?
> "128b/132b":"8b/10b", mst_state->mgr);
> +}
> +EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
> +
>  /**
>   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>   * @mgr: manager for this port
> @@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> drm_dp_mst_topology_mgr *mgr,
>  
>          ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
>          if (ret) {
> -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63
> ret=%d\n",
> -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=%d
> ret=%d\n",
> +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> >total_avail_slots, ret);
>                  drm_dp_mst_topology_put_port(port);
>                  goto out;
>          }
> @@ -5226,7 +5238,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> drm_dp_mst_topology_mgr *mgr,
>                                           struct drm_dp_mst_topology_state
> *mst_state)
>  {
>          struct drm_dp_vcpi_allocation *vcpi;
> -       int avail_slots = 63, payload_count = 0;
> +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
>  
>          list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>                  /* Releasing VCPI is always OK-even if the port is gone */
> @@ -5255,7 +5267,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> drm_dp_mst_topology_mgr *mgr,
>                  }
>          }
>          drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d
> used=%d\n",
> -                      mgr, mst_state, avail_slots, 63 - avail_slots);
> +                      mgr, mst_state, avail_slots, mgr->total_avail_slots -
> avail_slots);
>  
>          return 0;
>  }
> @@ -5421,6 +5433,10 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state
> *state)
>                          break;
>  
>                  mutex_lock(&mgr->lock);
> +
> +               mgr->start_slot = mst_state->start_slot;
> +               mgr->total_avail_slots = mst_state->total_avail_slots;
> +
>                  ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-
> >mst_primary,
>                                                              mst_state);
>                  mutex_unlock(&mgr->lock);
> @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
> drm_dp_mst_topology_mgr *mgr,
>          if (!mgr->proposed_vcpis)
>                  return -ENOMEM;
>          set_bit(0, &mgr->payload_mask);
> +       mgr->total_avail_slots = 63;
> +       mgr->start_slot = 1;
>  
>          mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>          if (mst_state == NULL)
>                  return -ENOMEM;
>  
> +       mst_state->total_avail_slots = 63;
> +       mst_state->start_slot = 1;
> +
>          mst_state->mgr = mgr;
>          INIT_LIST_HEAD(&mst_state->vcpis);
>  
> diff --git a/include/drm/drm_dp_mst_helper.h
> b/include/drm/drm_dp_mst_helper.h
> index ddb9231d0309..f8152dfb34ed 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
>          struct drm_private_state base;
>          struct list_head vcpis;
>          struct drm_dp_mst_topology_mgr *mgr;
> +       u8 total_avail_slots;
> +       u8 start_slot;
>  };
>  
>  #define to_dp_mst_topology_mgr(x) container_of(x, struct
> drm_dp_mst_topology_mgr, base)
> @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
>           */
>          int pbn_div;
>  
> +       /**
> +        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
> +        */
> +       u8 total_avail_slots;
> +
> +       /**
> +        * @start_slot: 1 for 8b/10b, 0 for 128/132b
> +        */
> +       u8 start_slot;
> +
>          /**
>           * @funcs: Atomic helper callbacks
>           */
> @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct
> drm_dp_mst_topology_mgr *mgr, struct drm_dp
>  
>  void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
> struct drm_dp_mst_port *port);
>  
> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
> *mst_state, uint8_t link_coding_cap);
>  
>  void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>                                  struct drm_dp_mst_port *port);

-- 
Cheers,
Lyude Paul (she/her)
Software Engineer at Red Hat

[-- Attachment #2: Type: text/html, Size: 19073 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-12 21:58         ` [PATCH] " Bhawanpreet Lakha
  2021-10-12 22:02           ` Lakha, Bhawanpreet
@ 2021-10-13 16:09           ` Jani Nikula
  2021-10-13 19:33             ` Bhawanpreet Lakha
  2021-10-13 18:52             ` kernel test robot
                             ` (2 subsequent siblings)
  4 siblings, 1 reply; 37+ messages in thread
From: Jani Nikula @ 2021-10-13 16:09 UTC (permalink / raw)
  To: Bhawanpreet Lakha, Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Bhawanpreet Lakha

On Tue, 12 Oct 2021, Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> wrote:
> 8b/10b encoding format requires to reserve the first slot for
> recording metadata. Real data transmission starts from the second slot,
> with a total of available 63 slots available.
>
> In 128b/132b encoding format, metadata is transmitted separately
> in LLCP packet before MTP. Real data transmission starts from
> the first slot, with a total of 64 slots available.
>
> v2:
> * Remove get_mst_link_encoding_cap
> * Move total/start slots to mst_state, and copy it to mst_mgr in
> atomic_check
>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++++++
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 35 +++++++++++++++----
>  include/drm/drm_dp_mst_helper.h               | 13 +++++++
>  3 files changed, 69 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 5020f2d36fe1..4ad50eb0091a 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -10612,6 +10612,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
>  	struct dsc_mst_fairness_vars vars[MAX_PIPES];
>  #endif
> +	struct drm_dp_mst_topology_state *mst_state;
> +	struct drm_dp_mst_topology_mgr *mgr;
>  
>  	trace_amdgpu_dm_atomic_check_begin(state);
>  
> @@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
>  		lock_and_validation_needed = true;
>  	}
>  
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +	for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
> +		struct amdgpu_dm_connector *aconnector;
> +		struct drm_connector *connector;
> +		struct drm_connector_list_iter iter;
> +		u8 link_coding_cap;
> +
> +		if (!mgr->mst_state )
> +			continue;
> +
> +		drm_connector_list_iter_begin(dev, &iter);
> +		drm_for_each_connector_iter(connector, &iter) {
> +			int id = connector->index;
> +
> +			if (id == mst_state->mgr->conn_base_id) {
> +				aconnector = to_amdgpu_dm_connector(connector);
> +				link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
> +				drm_dp_mst_update_coding_cap(mst_state, link_coding_cap);
> +
> +				break;
> +			}
> +		}
> +		drm_connector_list_iter_end(&iter);
> +
> +	}
> +#endif

I wonder if we could split this to separate drm dp helper and amd driver
patches?

>  	/**
>  	 * Streams and planes are reset when there are changes that affect
>  	 * bandwidth. Anything that affects bandwidth needs to go through
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> index ad0795afc21c..fb5c47c4cb2e 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
>  	struct drm_dp_payload req_payload;
>  	struct drm_dp_mst_port *port;
>  	int i, j;
> -	int cur_slots = 1;
> +	int cur_slots = mgr->start_slot;
>  	bool skip;
>  
>  	mutex_lock(&mgr->payload_lock);
> @@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
>  	num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
>  
>  	/* max. time slots - one slot for MTP header */
> -	if (num_slots > 63)
> +	if (num_slots > mgr->total_avail_slots)
>  		return -ENOSPC;
>  	return num_slots;
>  }
> @@ -4333,7 +4333,7 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>  	int ret;
>  
>  	/* max. time slots - one slot for MTP header */
> -	if (slots > 63)
> +	if (slots > mgr->total_avail_slots)
>  		return -ENOSPC;
>  
>  	vcpi->pbn = pbn;
> @@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
>  }
>  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>  
> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state *mst_state, uint8_t link_coding_cap)
> +{
> +	if (link_coding_cap == DP_CAP_ANSI_128B132B) {
> +		mst_state->total_avail_slots = 64;
> +		mst_state->start_slot = 0;
> +	}

The values never change AFAICT, should we store the channel encoding
instead, and use that information to initialize the values?

(Alternatively, why aren't the 8b/10b values initialized here if
128b/132b are?)

> +
> +	DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
> +			(link_coding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b", mst_state->mgr);
> +}
> +EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
> +
>  /**
>   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>   * @mgr: manager for this port
> @@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>  
>  	ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
>  	if (ret) {
> -		drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63 ret=%d\n",
> -			    DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> +		drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=%d ret=%d\n",
> +			    DIV_ROUND_UP(pbn, mgr->pbn_div), mgr->total_avail_slots, ret);
>  		drm_dp_mst_topology_put_port(port);
>  		goto out;
>  	}
> @@ -5226,7 +5238,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
>  					 struct drm_dp_mst_topology_state *mst_state)
>  {
>  	struct drm_dp_vcpi_allocation *vcpi;
> -	int avail_slots = 63, payload_count = 0;
> +	int avail_slots = mgr->total_avail_slots, payload_count = 0;

>  
>  	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>  		/* Releasing VCPI is always OK-even if the port is gone */
> @@ -5255,7 +5267,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
>  		}
>  	}
>  	drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
> -		       mgr, mst_state, avail_slots, 63 - avail_slots);
> +		       mgr, mst_state, avail_slots, mgr->total_avail_slots - avail_slots);
>  
>  	return 0;
>  }
> @@ -5421,6 +5433,10 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state *state)
>  			break;
>  
>  		mutex_lock(&mgr->lock);
> +
> +		mgr->start_slot = mst_state->start_slot;
> +		mgr->total_avail_slots = mst_state->total_avail_slots;
> +

It feels wrong to me to be copying stuff from mst_state to mgr in
general, and in atomic check hook in particular.

>  		ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,
>  							    mst_state);
>  		mutex_unlock(&mgr->lock);
> @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>  	if (!mgr->proposed_vcpis)
>  		return -ENOMEM;
>  	set_bit(0, &mgr->payload_mask);
> +	mgr->total_avail_slots = 63;
> +	mgr->start_slot = 1;
>  
>  	mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>  	if (mst_state == NULL)
>  		return -ENOMEM;
>  
> +	mst_state->total_avail_slots = 63;
> +	mst_state->start_slot = 1;
> +

The magic values for 8b/10b are now duplicated to two places, with the
128b/132b values in a separate place.

BR,
Jani.

>  	mst_state->mgr = mgr;
>  	INIT_LIST_HEAD(&mst_state->vcpis);
>  
> diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> index ddb9231d0309..f8152dfb34ed 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
>  	struct drm_private_state base;
>  	struct list_head vcpis;
>  	struct drm_dp_mst_topology_mgr *mgr;
> +	u8 total_avail_slots;
> +	u8 start_slot;
>  };
>  
>  #define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
> @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
>  	 */
>  	int pbn_div;
>  
> +	/**
> +	 * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
> +	 */
> +	u8 total_avail_slots;
> +
> +	/**
> +	 * @start_slot: 1 for 8b/10b, 0 for 128/132b
> +	 */
> +	u8 start_slot;
> +
>  	/**
>  	 * @funcs: Atomic helper callbacks
>  	 */
> @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
>  
>  void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
>  
> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state *mst_state, uint8_t link_coding_cap);
>  
>  void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>  				struct drm_dp_mst_port *port);

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-12 21:58         ` [PATCH] " Bhawanpreet Lakha
@ 2021-10-13 18:52             ` kernel test robot
  2021-10-13 16:09           ` Jani Nikula
                               ` (3 subsequent siblings)
  4 siblings, 0 replies; 37+ messages in thread
From: kernel test robot @ 2021-10-13 18:52 UTC (permalink / raw)
  To: Bhawanpreet Lakha, Jerry.Zuo, dri-devel, lyude
  Cc: kbuild-all, Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas,
	Bhawanpreet Lakha

[-- Attachment #1: Type: text/plain, Size: 15692 bytes --]

Hi Bhawanpreet,

Thank you for the patch! Yet something to improve:

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

url:    https://github.com/0day-ci/linux/commits/Bhawanpreet-Lakha/drm-Update-MST-First-Link-Slot-Information-Based-on-Encoding-Format/20211013-060001
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: i386-randconfig-a003-20211012 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/5604bf980dcbfdd7650b7e1d5d4a2fd9f18cd866
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Bhawanpreet-Lakha/drm-Update-MST-First-Link-Slot-Information-Based-on-Encoding-Format/20211013-060001
        git checkout 5604bf980dcbfdd7650b7e1d5d4a2fd9f18cd866
        # save the attached .config to linux build tree
        make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/amd/amdgpu/../display/dmub/dmub_srv.h:67,
                    from drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:35:
   drivers/gpu/drm/amd/amdgpu/../display/dmub/inc/dmub_cmd.h: In function 'dmub_rb_flush_pending':
   drivers/gpu/drm/amd/amdgpu/../display/dmub/inc/dmub_cmd.h:2819:12: warning: variable 'temp' set but not used [-Wunused-but-set-variable]
    2819 |   uint64_t temp;
         |            ^~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: At top level:
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:633:6: warning: no previous prototype for 'dmub_aux_setconfig_callback' [-Wmissing-prototypes]
     633 | void dmub_aux_setconfig_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:649:6: warning: no previous prototype for 'dmub_hpd_callback' [-Wmissing-prototypes]
     649 | void dmub_hpd_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
         |      ^~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:706:6: warning: no previous prototype for 'register_dmub_notify_callback' [-Wmissing-prototypes]
     706 | bool register_dmub_notify_callback(struct amdgpu_device *adev, enum dmub_notification_type type,
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: In function 'dm_update_mst_vcpi_slots_for_dsc':
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:7174:12: warning: variable 'clock' set but not used [-Wunused-but-set-variable]
    7174 |  int i, j, clock;
         |            ^~~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: In function 'amdgpu_dm_atomic_check':
>> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:10912:23: error: implicit declaration of function 'dc_link_dp_mst_decide_link_encoding_format' [-Werror=implicit-function-declaration]
   10912 |     link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
         |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: At top level:
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:11394:5: warning: no previous prototype for 'amdgpu_dm_set_dmub_async_sync_status' [-Wmissing-prototypes]
   11394 | int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux, struct dc_context *ctx,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +/dc_link_dp_mst_decide_link_encoding_format +10912 drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c

 10643	
 10644	/**
 10645	 * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
 10646	 * @dev: The DRM device
 10647	 * @state: The atomic state to commit
 10648	 *
 10649	 * Validate that the given atomic state is programmable by DC into hardware.
 10650	 * This involves constructing a &struct dc_state reflecting the new hardware
 10651	 * state we wish to commit, then querying DC to see if it is programmable. It's
 10652	 * important not to modify the existing DC state. Otherwise, atomic_check
 10653	 * may unexpectedly commit hardware changes.
 10654	 *
 10655	 * When validating the DC state, it's important that the right locks are
 10656	 * acquired. For full updates case which removes/adds/updates streams on one
 10657	 * CRTC while flipping on another CRTC, acquiring global lock will guarantee
 10658	 * that any such full update commit will wait for completion of any outstanding
 10659	 * flip using DRMs synchronization events.
 10660	 *
 10661	 * Note that DM adds the affected connectors for all CRTCs in state, when that
 10662	 * might not seem necessary. This is because DC stream creation requires the
 10663	 * DC sink, which is tied to the DRM connector state. Cleaning this up should
 10664	 * be possible but non-trivial - a possible TODO item.
 10665	 *
 10666	 * Return: -Error code if validation failed.
 10667	 */
 10668	static int amdgpu_dm_atomic_check(struct drm_device *dev,
 10669					  struct drm_atomic_state *state)
 10670	{
 10671		struct amdgpu_device *adev = drm_to_adev(dev);
 10672		struct dm_atomic_state *dm_state = NULL;
 10673		struct dc *dc = adev->dm.dc;
 10674		struct drm_connector *connector;
 10675		struct drm_connector_state *old_con_state, *new_con_state;
 10676		struct drm_crtc *crtc;
 10677		struct drm_crtc_state *old_crtc_state, *new_crtc_state;
 10678		struct drm_plane *plane;
 10679		struct drm_plane_state *old_plane_state, *new_plane_state;
 10680		enum dc_status status;
 10681		int ret, i;
 10682		bool lock_and_validation_needed = false;
 10683		struct dm_crtc_state *dm_old_crtc_state;
 10684	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10685		struct dsc_mst_fairness_vars vars[MAX_PIPES];
 10686	#endif
 10687		struct drm_dp_mst_topology_state *mst_state;
 10688		struct drm_dp_mst_topology_mgr *mgr;
 10689	
 10690		trace_amdgpu_dm_atomic_check_begin(state);
 10691	
 10692		ret = drm_atomic_helper_check_modeset(dev, state);
 10693		if (ret)
 10694			goto fail;
 10695	
 10696		/* Check connector changes */
 10697		for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
 10698			struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
 10699			struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 10700	
 10701			/* Skip connectors that are disabled or part of modeset already. */
 10702			if (!old_con_state->crtc && !new_con_state->crtc)
 10703				continue;
 10704	
 10705			if (!new_con_state->crtc)
 10706				continue;
 10707	
 10708			new_crtc_state = drm_atomic_get_crtc_state(state, new_con_state->crtc);
 10709			if (IS_ERR(new_crtc_state)) {
 10710				ret = PTR_ERR(new_crtc_state);
 10711				goto fail;
 10712			}
 10713	
 10714			if (dm_old_con_state->abm_level !=
 10715			    dm_new_con_state->abm_level)
 10716				new_crtc_state->connectors_changed = true;
 10717		}
 10718	
 10719	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10720		if (dc_resource_is_dsc_encoding_supported(dc)) {
 10721			for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10722				if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
 10723					ret = add_affected_mst_dsc_crtcs(state, crtc);
 10724					if (ret)
 10725						goto fail;
 10726				}
 10727			}
 10728		}
 10729	#endif
 10730		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10731			dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
 10732	
 10733			if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
 10734			    !new_crtc_state->color_mgmt_changed &&
 10735			    old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled &&
 10736				dm_old_crtc_state->dsc_force_changed == false)
 10737				continue;
 10738	
 10739			ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);
 10740			if (ret)
 10741				goto fail;
 10742	
 10743			if (!new_crtc_state->enable)
 10744				continue;
 10745	
 10746			ret = drm_atomic_add_affected_connectors(state, crtc);
 10747			if (ret)
 10748				return ret;
 10749	
 10750			ret = drm_atomic_add_affected_planes(state, crtc);
 10751			if (ret)
 10752				goto fail;
 10753	
 10754			if (dm_old_crtc_state->dsc_force_changed)
 10755				new_crtc_state->mode_changed = true;
 10756		}
 10757	
 10758		/*
 10759		 * Add all primary and overlay planes on the CRTC to the state
 10760		 * whenever a plane is enabled to maintain correct z-ordering
 10761		 * and to enable fast surface updates.
 10762		 */
 10763		drm_for_each_crtc(crtc, dev) {
 10764			bool modified = false;
 10765	
 10766			for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
 10767				if (plane->type == DRM_PLANE_TYPE_CURSOR)
 10768					continue;
 10769	
 10770				if (new_plane_state->crtc == crtc ||
 10771				    old_plane_state->crtc == crtc) {
 10772					modified = true;
 10773					break;
 10774				}
 10775			}
 10776	
 10777			if (!modified)
 10778				continue;
 10779	
 10780			drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) {
 10781				if (plane->type == DRM_PLANE_TYPE_CURSOR)
 10782					continue;
 10783	
 10784				new_plane_state =
 10785					drm_atomic_get_plane_state(state, plane);
 10786	
 10787				if (IS_ERR(new_plane_state)) {
 10788					ret = PTR_ERR(new_plane_state);
 10789					goto fail;
 10790				}
 10791			}
 10792		}
 10793	
 10794		/* Remove exiting planes if they are modified */
 10795		for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
 10796			ret = dm_update_plane_state(dc, state, plane,
 10797						    old_plane_state,
 10798						    new_plane_state,
 10799						    false,
 10800						    &lock_and_validation_needed);
 10801			if (ret)
 10802				goto fail;
 10803		}
 10804	
 10805		/* Disable all crtcs which require disable */
 10806		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10807			ret = dm_update_crtc_state(&adev->dm, state, crtc,
 10808						   old_crtc_state,
 10809						   new_crtc_state,
 10810						   false,
 10811						   &lock_and_validation_needed);
 10812			if (ret)
 10813				goto fail;
 10814		}
 10815	
 10816		/* Enable all crtcs which require enable */
 10817		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10818			ret = dm_update_crtc_state(&adev->dm, state, crtc,
 10819						   old_crtc_state,
 10820						   new_crtc_state,
 10821						   true,
 10822						   &lock_and_validation_needed);
 10823			if (ret)
 10824				goto fail;
 10825		}
 10826	
 10827		ret = validate_overlay(state);
 10828		if (ret)
 10829			goto fail;
 10830	
 10831		/* Add new/modified planes */
 10832		for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
 10833			ret = dm_update_plane_state(dc, state, plane,
 10834						    old_plane_state,
 10835						    new_plane_state,
 10836						    true,
 10837						    &lock_and_validation_needed);
 10838			if (ret)
 10839				goto fail;
 10840		}
 10841	
 10842		/* Run this here since we want to validate the streams we created */
 10843		ret = drm_atomic_helper_check_planes(dev, state);
 10844		if (ret)
 10845			goto fail;
 10846	
 10847		/* Check cursor planes scaling */
 10848		for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
 10849			ret = dm_check_crtc_cursor(state, crtc, new_crtc_state);
 10850			if (ret)
 10851				goto fail;
 10852		}
 10853	
 10854		if (state->legacy_cursor_update) {
 10855			/*
 10856			 * This is a fast cursor update coming from the plane update
 10857			 * helper, check if it can be done asynchronously for better
 10858			 * performance.
 10859			 */
 10860			state->async_update =
 10861				!drm_atomic_helper_async_check(dev, state);
 10862	
 10863			/*
 10864			 * Skip the remaining global validation if this is an async
 10865			 * update. Cursor updates can be done without affecting
 10866			 * state or bandwidth calcs and this avoids the performance
 10867			 * penalty of locking the private state object and
 10868			 * allocating a new dc_state.
 10869			 */
 10870			if (state->async_update)
 10871				return 0;
 10872		}
 10873	
 10874		/* Check scaling and underscan changes*/
 10875		/* TODO Removed scaling changes validation due to inability to commit
 10876		 * new stream into context w\o causing full reset. Need to
 10877		 * decide how to handle.
 10878		 */
 10879		for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
 10880			struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
 10881			struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 10882			struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
 10883	
 10884			/* Skip any modesets/resets */
 10885			if (!acrtc || drm_atomic_crtc_needs_modeset(
 10886					drm_atomic_get_new_crtc_state(state, &acrtc->base)))
 10887				continue;
 10888	
 10889			/* Skip any thing not scale or underscan changes */
 10890			if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state))
 10891				continue;
 10892	
 10893			lock_and_validation_needed = true;
 10894		}
 10895	
 10896	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10897		for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
 10898			struct amdgpu_dm_connector *aconnector;
 10899			struct drm_connector *connector;
 10900			struct drm_connector_list_iter iter;
 10901			u8 link_coding_cap;
 10902	
 10903			if (!mgr->mst_state )
 10904				continue;
 10905	
 10906			drm_connector_list_iter_begin(dev, &iter);
 10907			drm_for_each_connector_iter(connector, &iter) {
 10908				int id = connector->index;
 10909	
 10910				if (id == mst_state->mgr->conn_base_id) {
 10911					aconnector = to_amdgpu_dm_connector(connector);
 10912					link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
 10913					drm_dp_mst_update_coding_cap(mst_state, link_coding_cap);
 10914	
 10915					break;
 10916				}
 10917			}
 10918			drm_connector_list_iter_end(&iter);
 10919	
 10920		}
 10921	#endif
 10922		/**
 10923		 * Streams and planes are reset when there are changes that affect
 10924		 * bandwidth. Anything that affects bandwidth needs to go through
 10925		 * DC global validation to ensure that the configuration can be applied
 10926		 * to hardware.
 10927		 *
 10928		 * We have to currently stall out here in atomic_check for outstanding
 10929		 * commits to finish in this case because our IRQ handlers reference
 10930		 * DRM state directly - we can end up disabling interrupts too early
 10931		 * if we don't.
 10932		 *
 10933		 * TODO: Remove this stall and drop DM state private objects.
 10934		 */
 10935		if (lock_and_validation_needed) {
 10936			ret = dm_atomic_get_state(state, &dm_state);
 10937			if (ret)
 10938				goto fail;
 10939	
 10940			ret = do_aquire_global_lock(dev, state);
 10941			if (ret)
 10942				goto fail;
 10943	

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 39598 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
@ 2021-10-13 18:52             ` kernel test robot
  0 siblings, 0 replies; 37+ messages in thread
From: kernel test robot @ 2021-10-13 18:52 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 16060 bytes --]

Hi Bhawanpreet,

Thank you for the patch! Yet something to improve:

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

url:    https://github.com/0day-ci/linux/commits/Bhawanpreet-Lakha/drm-Update-MST-First-Link-Slot-Information-Based-on-Encoding-Format/20211013-060001
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: i386-randconfig-a003-20211012 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/5604bf980dcbfdd7650b7e1d5d4a2fd9f18cd866
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Bhawanpreet-Lakha/drm-Update-MST-First-Link-Slot-Information-Based-on-Encoding-Format/20211013-060001
        git checkout 5604bf980dcbfdd7650b7e1d5d4a2fd9f18cd866
        # save the attached .config to linux build tree
        make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/amd/amdgpu/../display/dmub/dmub_srv.h:67,
                    from drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:35:
   drivers/gpu/drm/amd/amdgpu/../display/dmub/inc/dmub_cmd.h: In function 'dmub_rb_flush_pending':
   drivers/gpu/drm/amd/amdgpu/../display/dmub/inc/dmub_cmd.h:2819:12: warning: variable 'temp' set but not used [-Wunused-but-set-variable]
    2819 |   uint64_t temp;
         |            ^~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: At top level:
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:633:6: warning: no previous prototype for 'dmub_aux_setconfig_callback' [-Wmissing-prototypes]
     633 | void dmub_aux_setconfig_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:649:6: warning: no previous prototype for 'dmub_hpd_callback' [-Wmissing-prototypes]
     649 | void dmub_hpd_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
         |      ^~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:706:6: warning: no previous prototype for 'register_dmub_notify_callback' [-Wmissing-prototypes]
     706 | bool register_dmub_notify_callback(struct amdgpu_device *adev, enum dmub_notification_type type,
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: In function 'dm_update_mst_vcpi_slots_for_dsc':
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:7174:12: warning: variable 'clock' set but not used [-Wunused-but-set-variable]
    7174 |  int i, j, clock;
         |            ^~~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: In function 'amdgpu_dm_atomic_check':
>> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:10912:23: error: implicit declaration of function 'dc_link_dp_mst_decide_link_encoding_format' [-Werror=implicit-function-declaration]
   10912 |     link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
         |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: At top level:
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:11394:5: warning: no previous prototype for 'amdgpu_dm_set_dmub_async_sync_status' [-Wmissing-prototypes]
   11394 | int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux, struct dc_context *ctx,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +/dc_link_dp_mst_decide_link_encoding_format +10912 drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c

 10643	
 10644	/**
 10645	 * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
 10646	 * @dev: The DRM device
 10647	 * @state: The atomic state to commit
 10648	 *
 10649	 * Validate that the given atomic state is programmable by DC into hardware.
 10650	 * This involves constructing a &struct dc_state reflecting the new hardware
 10651	 * state we wish to commit, then querying DC to see if it is programmable. It's
 10652	 * important not to modify the existing DC state. Otherwise, atomic_check
 10653	 * may unexpectedly commit hardware changes.
 10654	 *
 10655	 * When validating the DC state, it's important that the right locks are
 10656	 * acquired. For full updates case which removes/adds/updates streams on one
 10657	 * CRTC while flipping on another CRTC, acquiring global lock will guarantee
 10658	 * that any such full update commit will wait for completion of any outstanding
 10659	 * flip using DRMs synchronization events.
 10660	 *
 10661	 * Note that DM adds the affected connectors for all CRTCs in state, when that
 10662	 * might not seem necessary. This is because DC stream creation requires the
 10663	 * DC sink, which is tied to the DRM connector state. Cleaning this up should
 10664	 * be possible but non-trivial - a possible TODO item.
 10665	 *
 10666	 * Return: -Error code if validation failed.
 10667	 */
 10668	static int amdgpu_dm_atomic_check(struct drm_device *dev,
 10669					  struct drm_atomic_state *state)
 10670	{
 10671		struct amdgpu_device *adev = drm_to_adev(dev);
 10672		struct dm_atomic_state *dm_state = NULL;
 10673		struct dc *dc = adev->dm.dc;
 10674		struct drm_connector *connector;
 10675		struct drm_connector_state *old_con_state, *new_con_state;
 10676		struct drm_crtc *crtc;
 10677		struct drm_crtc_state *old_crtc_state, *new_crtc_state;
 10678		struct drm_plane *plane;
 10679		struct drm_plane_state *old_plane_state, *new_plane_state;
 10680		enum dc_status status;
 10681		int ret, i;
 10682		bool lock_and_validation_needed = false;
 10683		struct dm_crtc_state *dm_old_crtc_state;
 10684	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10685		struct dsc_mst_fairness_vars vars[MAX_PIPES];
 10686	#endif
 10687		struct drm_dp_mst_topology_state *mst_state;
 10688		struct drm_dp_mst_topology_mgr *mgr;
 10689	
 10690		trace_amdgpu_dm_atomic_check_begin(state);
 10691	
 10692		ret = drm_atomic_helper_check_modeset(dev, state);
 10693		if (ret)
 10694			goto fail;
 10695	
 10696		/* Check connector changes */
 10697		for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
 10698			struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
 10699			struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 10700	
 10701			/* Skip connectors that are disabled or part of modeset already. */
 10702			if (!old_con_state->crtc && !new_con_state->crtc)
 10703				continue;
 10704	
 10705			if (!new_con_state->crtc)
 10706				continue;
 10707	
 10708			new_crtc_state = drm_atomic_get_crtc_state(state, new_con_state->crtc);
 10709			if (IS_ERR(new_crtc_state)) {
 10710				ret = PTR_ERR(new_crtc_state);
 10711				goto fail;
 10712			}
 10713	
 10714			if (dm_old_con_state->abm_level !=
 10715			    dm_new_con_state->abm_level)
 10716				new_crtc_state->connectors_changed = true;
 10717		}
 10718	
 10719	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10720		if (dc_resource_is_dsc_encoding_supported(dc)) {
 10721			for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10722				if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
 10723					ret = add_affected_mst_dsc_crtcs(state, crtc);
 10724					if (ret)
 10725						goto fail;
 10726				}
 10727			}
 10728		}
 10729	#endif
 10730		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10731			dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
 10732	
 10733			if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
 10734			    !new_crtc_state->color_mgmt_changed &&
 10735			    old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled &&
 10736				dm_old_crtc_state->dsc_force_changed == false)
 10737				continue;
 10738	
 10739			ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);
 10740			if (ret)
 10741				goto fail;
 10742	
 10743			if (!new_crtc_state->enable)
 10744				continue;
 10745	
 10746			ret = drm_atomic_add_affected_connectors(state, crtc);
 10747			if (ret)
 10748				return ret;
 10749	
 10750			ret = drm_atomic_add_affected_planes(state, crtc);
 10751			if (ret)
 10752				goto fail;
 10753	
 10754			if (dm_old_crtc_state->dsc_force_changed)
 10755				new_crtc_state->mode_changed = true;
 10756		}
 10757	
 10758		/*
 10759		 * Add all primary and overlay planes on the CRTC to the state
 10760		 * whenever a plane is enabled to maintain correct z-ordering
 10761		 * and to enable fast surface updates.
 10762		 */
 10763		drm_for_each_crtc(crtc, dev) {
 10764			bool modified = false;
 10765	
 10766			for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
 10767				if (plane->type == DRM_PLANE_TYPE_CURSOR)
 10768					continue;
 10769	
 10770				if (new_plane_state->crtc == crtc ||
 10771				    old_plane_state->crtc == crtc) {
 10772					modified = true;
 10773					break;
 10774				}
 10775			}
 10776	
 10777			if (!modified)
 10778				continue;
 10779	
 10780			drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) {
 10781				if (plane->type == DRM_PLANE_TYPE_CURSOR)
 10782					continue;
 10783	
 10784				new_plane_state =
 10785					drm_atomic_get_plane_state(state, plane);
 10786	
 10787				if (IS_ERR(new_plane_state)) {
 10788					ret = PTR_ERR(new_plane_state);
 10789					goto fail;
 10790				}
 10791			}
 10792		}
 10793	
 10794		/* Remove exiting planes if they are modified */
 10795		for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
 10796			ret = dm_update_plane_state(dc, state, plane,
 10797						    old_plane_state,
 10798						    new_plane_state,
 10799						    false,
 10800						    &lock_and_validation_needed);
 10801			if (ret)
 10802				goto fail;
 10803		}
 10804	
 10805		/* Disable all crtcs which require disable */
 10806		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10807			ret = dm_update_crtc_state(&adev->dm, state, crtc,
 10808						   old_crtc_state,
 10809						   new_crtc_state,
 10810						   false,
 10811						   &lock_and_validation_needed);
 10812			if (ret)
 10813				goto fail;
 10814		}
 10815	
 10816		/* Enable all crtcs which require enable */
 10817		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10818			ret = dm_update_crtc_state(&adev->dm, state, crtc,
 10819						   old_crtc_state,
 10820						   new_crtc_state,
 10821						   true,
 10822						   &lock_and_validation_needed);
 10823			if (ret)
 10824				goto fail;
 10825		}
 10826	
 10827		ret = validate_overlay(state);
 10828		if (ret)
 10829			goto fail;
 10830	
 10831		/* Add new/modified planes */
 10832		for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
 10833			ret = dm_update_plane_state(dc, state, plane,
 10834						    old_plane_state,
 10835						    new_plane_state,
 10836						    true,
 10837						    &lock_and_validation_needed);
 10838			if (ret)
 10839				goto fail;
 10840		}
 10841	
 10842		/* Run this here since we want to validate the streams we created */
 10843		ret = drm_atomic_helper_check_planes(dev, state);
 10844		if (ret)
 10845			goto fail;
 10846	
 10847		/* Check cursor planes scaling */
 10848		for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
 10849			ret = dm_check_crtc_cursor(state, crtc, new_crtc_state);
 10850			if (ret)
 10851				goto fail;
 10852		}
 10853	
 10854		if (state->legacy_cursor_update) {
 10855			/*
 10856			 * This is a fast cursor update coming from the plane update
 10857			 * helper, check if it can be done asynchronously for better
 10858			 * performance.
 10859			 */
 10860			state->async_update =
 10861				!drm_atomic_helper_async_check(dev, state);
 10862	
 10863			/*
 10864			 * Skip the remaining global validation if this is an async
 10865			 * update. Cursor updates can be done without affecting
 10866			 * state or bandwidth calcs and this avoids the performance
 10867			 * penalty of locking the private state object and
 10868			 * allocating a new dc_state.
 10869			 */
 10870			if (state->async_update)
 10871				return 0;
 10872		}
 10873	
 10874		/* Check scaling and underscan changes*/
 10875		/* TODO Removed scaling changes validation due to inability to commit
 10876		 * new stream into context w\o causing full reset. Need to
 10877		 * decide how to handle.
 10878		 */
 10879		for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
 10880			struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
 10881			struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 10882			struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
 10883	
 10884			/* Skip any modesets/resets */
 10885			if (!acrtc || drm_atomic_crtc_needs_modeset(
 10886					drm_atomic_get_new_crtc_state(state, &acrtc->base)))
 10887				continue;
 10888	
 10889			/* Skip any thing not scale or underscan changes */
 10890			if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state))
 10891				continue;
 10892	
 10893			lock_and_validation_needed = true;
 10894		}
 10895	
 10896	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10897		for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
 10898			struct amdgpu_dm_connector *aconnector;
 10899			struct drm_connector *connector;
 10900			struct drm_connector_list_iter iter;
 10901			u8 link_coding_cap;
 10902	
 10903			if (!mgr->mst_state )
 10904				continue;
 10905	
 10906			drm_connector_list_iter_begin(dev, &iter);
 10907			drm_for_each_connector_iter(connector, &iter) {
 10908				int id = connector->index;
 10909	
 10910				if (id == mst_state->mgr->conn_base_id) {
 10911					aconnector = to_amdgpu_dm_connector(connector);
 10912					link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
 10913					drm_dp_mst_update_coding_cap(mst_state, link_coding_cap);
 10914	
 10915					break;
 10916				}
 10917			}
 10918			drm_connector_list_iter_end(&iter);
 10919	
 10920		}
 10921	#endif
 10922		/**
 10923		 * Streams and planes are reset when there are changes that affect
 10924		 * bandwidth. Anything that affects bandwidth needs to go through
 10925		 * DC global validation to ensure that the configuration can be applied
 10926		 * to hardware.
 10927		 *
 10928		 * We have to currently stall out here in atomic_check for outstanding
 10929		 * commits to finish in this case because our IRQ handlers reference
 10930		 * DRM state directly - we can end up disabling interrupts too early
 10931		 * if we don't.
 10932		 *
 10933		 * TODO: Remove this stall and drop DM state private objects.
 10934		 */
 10935		if (lock_and_validation_needed) {
 10936			ret = dm_atomic_get_state(state, &dm_state);
 10937			if (ret)
 10938				goto fail;
 10939	
 10940			ret = do_aquire_global_lock(dev, state);
 10941			if (ret)
 10942				goto fail;
 10943	

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

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 39598 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-13 16:09           ` Jani Nikula
@ 2021-10-13 19:33             ` Bhawanpreet Lakha
  2021-10-13 19:37               ` Lyude Paul
  0 siblings, 1 reply; 37+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-13 19:33 UTC (permalink / raw)
  To: Jani Nikula, Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas


On 2021-10-13 12:09 p.m., Jani Nikula wrote:
> On Tue, 12 Oct 2021, Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> wrote:
>> 8b/10b encoding format requires to reserve the first slot for
>> recording metadata. Real data transmission starts from the second slot,
>> with a total of available 63 slots available.
>>
>> In 128b/132b encoding format, metadata is transmitted separately
>> in LLCP packet before MTP. Real data transmission starts from
>> the first slot, with a total of 64 slots available.
>>
>> v2:
>> * Remove get_mst_link_encoding_cap
>> * Move total/start slots to mst_state, and copy it to mst_mgr in
>> atomic_check
>>
>> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
>> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
>> ---
>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++++++
>>   drivers/gpu/drm/drm_dp_mst_topology.c         | 35 +++++++++++++++----
>>   include/drm/drm_dp_mst_helper.h               | 13 +++++++
>>   3 files changed, 69 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> index 5020f2d36fe1..4ad50eb0091a 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -10612,6 +10612,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
>>   #if defined(CONFIG_DRM_AMD_DC_DCN)
>>   	struct dsc_mst_fairness_vars vars[MAX_PIPES];
>>   #endif
>> +	struct drm_dp_mst_topology_state *mst_state;
>> +	struct drm_dp_mst_topology_mgr *mgr;
>>   
>>   	trace_amdgpu_dm_atomic_check_begin(state);
>>   
>> @@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
>>   		lock_and_validation_needed = true;
>>   	}
>>   
>> +#if defined(CONFIG_DRM_AMD_DC_DCN)
>> +	for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
>> +		struct amdgpu_dm_connector *aconnector;
>> +		struct drm_connector *connector;
>> +		struct drm_connector_list_iter iter;
>> +		u8 link_coding_cap;
>> +
>> +		if (!mgr->mst_state )
>> +			continue;
>> +
>> +		drm_connector_list_iter_begin(dev, &iter);
>> +		drm_for_each_connector_iter(connector, &iter) {
>> +			int id = connector->index;
>> +
>> +			if (id == mst_state->mgr->conn_base_id) {
>> +				aconnector = to_amdgpu_dm_connector(connector);
>> +				link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
>> +				drm_dp_mst_update_coding_cap(mst_state, link_coding_cap);
>> +
>> +				break;
>> +			}
>> +		}
>> +		drm_connector_list_iter_end(&iter);
>> +
>> +	}
>> +#endif
> I wonder if we could split this to separate drm dp helper and amd driver
> patches?
>
I believe that was the original structure but, lyude recommended to put 
them into the same patch to see how it is being used
>>   	/**
>>   	 * Streams and planes are reset when there are changes that affect
>>   	 * bandwidth. Anything that affects bandwidth needs to go through
>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
>> index ad0795afc21c..fb5c47c4cb2e 100644
>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>> @@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
>>   	struct drm_dp_payload req_payload;
>>   	struct drm_dp_mst_port *port;
>>   	int i, j;
>> -	int cur_slots = 1;
>> +	int cur_slots = mgr->start_slot;
>>   	bool skip;
>>   
>>   	mutex_lock(&mgr->payload_lock);
>> @@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
>>   	num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
>>   
>>   	/* max. time slots - one slot for MTP header */
>> -	if (num_slots > 63)
>> +	if (num_slots > mgr->total_avail_slots)
>>   		return -ENOSPC;
>>   	return num_slots;
>>   }
>> @@ -4333,7 +4333,7 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>>   	int ret;
>>   
>>   	/* max. time slots - one slot for MTP header */
>> -	if (slots > 63)
>> +	if (slots > mgr->total_avail_slots)
>>   		return -ENOSPC;
>>   
>>   	vcpi->pbn = pbn;
>> @@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
>>   }
>>   EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>>   
>> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state *mst_state, uint8_t link_coding_cap)
>> +{
>> +	if (link_coding_cap == DP_CAP_ANSI_128B132B) {
>> +		mst_state->total_avail_slots = 64;
>> +		mst_state->start_slot = 0;
>> +	}
> The values never change AFAICT, should we store the channel encoding
> instead, and use that information to initialize the values?
>
> (Alternatively, why aren't the 8b/10b values initialized here if
> 128b/132b are?)
I agree, 8b/10 are the default, but in case where we switch from 
128b/132 -> 8b/10b we should be updating them here aswell.
>> +
>> +	DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
>> +			(link_coding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b", mst_state->mgr);
>> +}
>> +EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
>> +
>>   /**
>>    * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>>    * @mgr: manager for this port
>> @@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>>   
>>   	ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
>>   	if (ret) {
>> -		drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63 ret=%d\n",
>> -			    DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
>> +		drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=%d ret=%d\n",
>> +			    DIV_ROUND_UP(pbn, mgr->pbn_div), mgr->total_avail_slots, ret);
>>   		drm_dp_mst_topology_put_port(port);
>>   		goto out;
>>   	}
>> @@ -5226,7 +5238,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
>>   					 struct drm_dp_mst_topology_state *mst_state)
>>   {
>>   	struct drm_dp_vcpi_allocation *vcpi;
>> -	int avail_slots = 63, payload_count = 0;
>> +	int avail_slots = mgr->total_avail_slots, payload_count = 0;
>>   
>>   	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>>   		/* Releasing VCPI is always OK-even if the port is gone */
>> @@ -5255,7 +5267,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
>>   		}
>>   	}
>>   	drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
>> -		       mgr, mst_state, avail_slots, 63 - avail_slots);
>> +		       mgr, mst_state, avail_slots, mgr->total_avail_slots - avail_slots);
>>   
>>   	return 0;
>>   }
>> @@ -5421,6 +5433,10 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state *state)
>>   			break;
>>   
>>   		mutex_lock(&mgr->lock);
>> +
>> +		mgr->start_slot = mst_state->start_slot;
>> +		mgr->total_avail_slots = mst_state->total_avail_slots;
>> +
> It feels wrong to me to be copying stuff from mst_state to mgr in
> general, and in atomic check hook in particular.
previously we were setting it directly in the mgr, and this was 
suggested by lyude. I am not sure what the alternative is.
>>   		ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,
>>   							    mst_state);
>>   		mutex_unlock(&mgr->lock);
>> @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>   	if (!mgr->proposed_vcpis)
>>   		return -ENOMEM;
>>   	set_bit(0, &mgr->payload_mask);
>> +	mgr->total_avail_slots = 63;
>> +	mgr->start_slot = 1;
>>   
>>   	mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>>   	if (mst_state == NULL)
>>   		return -ENOMEM;
>>   
>> +	mst_state->total_avail_slots = 63;
>> +	mst_state->start_slot = 1;
>> +
> The magic values for 8b/10b are now duplicated to two places, with the
> 128b/132b values in a separate place.

8b/10b is the default (to make sure we don't break any existing driver 
that doesn't use 128b/132b). Are you against setting it as the default 
here? or do you mean we should use #define for this? the magic numbers 
are currently being used directly right now (inside 
drm_dp_find_vcpi_slots, drm_dp_init_vcpi).

Bhawan

> BR,
> Jani.
>
>>   	mst_state->mgr = mgr;
>>   	INIT_LIST_HEAD(&mst_state->vcpis);
>>   
>> diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
>> index ddb9231d0309..f8152dfb34ed 100644
>> --- a/include/drm/drm_dp_mst_helper.h
>> +++ b/include/drm/drm_dp_mst_helper.h
>> @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
>>   	struct drm_private_state base;
>>   	struct list_head vcpis;
>>   	struct drm_dp_mst_topology_mgr *mgr;
>> +	u8 total_avail_slots;
>> +	u8 start_slot;
>>   };
>>   
>>   #define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
>> @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
>>   	 */
>>   	int pbn_div;
>>   
>> +	/**
>> +	 * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
>> +	 */
>> +	u8 total_avail_slots;
>> +
>> +	/**
>> +	 * @start_slot: 1 for 8b/10b, 0 for 128/132b
>> +	 */
>> +	u8 start_slot;
>> +
>>   	/**
>>   	 * @funcs: Atomic helper callbacks
>>   	 */
>> @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
>>   
>>   void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
>>   
>> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state *mst_state, uint8_t link_coding_cap);
>>   
>>   void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>>   				struct drm_dp_mst_port *port);

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-13 19:33             ` Bhawanpreet Lakha
@ 2021-10-13 19:37               ` Lyude Paul
  0 siblings, 0 replies; 37+ messages in thread
From: Lyude Paul @ 2021-10-13 19:37 UTC (permalink / raw)
  To: Bhawanpreet Lakha, Jani Nikula, Jerry.Zuo, dri-devel
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas

On Wed, 2021-10-13 at 15:33 -0400, Bhawanpreet Lakha wrote:
> 
> > I wonder if we could split this to separate drm dp helper and amd driver
> > patches?

Whoops! I thought it was strange that I would say this but it seems there was
a misunderstanding on my part: when the original patch series was submitted I
was only CC'd on the first patch and I guess I must not have noticed the 1/2
in the subject line, so I thought Jerry had submitted just a single patch for
the helper. Looking back in my email history though that definitely wasn't
correct, and the original patch structure was what we wanted to go with.

Sorry for the confusion on my part!

> > 
> I believe that was the original structure but, lyude recommended to put 
> them into the same patch to see how it is being used
> > >         /**
> > >          * Streams and planes are reset when there are changes that
> > > affect
> > >          * bandwidth. Anything that affects bandwidth needs to go
> > > through
> > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > index ad0795afc21c..fb5c47c4cb2e 100644
> > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > @@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct
> > > drm_dp_mst_topology_mgr *mgr)
> > >         struct drm_dp_payload req_payload;
> > >         struct drm_dp_mst_port *port;
> > >         int i, j;
> > > -       int cur_slots = 1;
> > > +       int cur_slots = mgr->start_slot;
> > >         bool skip;
> > >   
> > >         mutex_lock(&mgr->payload_lock);
> > > @@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
> > >   
> > >         /* max. time slots - one slot for MTP header */
> > > -       if (num_slots > 63)
> > > +       if (num_slots > mgr->total_avail_slots)
> > >                 return -ENOSPC;
> > >         return num_slots;
> > >   }
> > > @@ -4333,7 +4333,7 @@ static int drm_dp_init_vcpi(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >         int ret;
> > >   
> > >         /* max. time slots - one slot for MTP header */
> > > -       if (slots > 63)
> > > +       if (slots > mgr->total_avail_slots)
> > >                 return -ENOSPC;
> > >   
> > >         vcpi->pbn = pbn;
> > > @@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct
> > > drm_atomic_state *state,
> > >   }
> > >   EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
> > >   
> > > +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
> > > *mst_state, uint8_t link_coding_cap)
> > > +{
> > > +       if (link_coding_cap == DP_CAP_ANSI_128B132B) {
> > > +               mst_state->total_avail_slots = 64;
> > > +               mst_state->start_slot = 0;
> > > +       }
> > The values never change AFAICT, should we store the channel encoding
> > instead, and use that information to initialize the values?
> > 
> > (Alternatively, why aren't the 8b/10b values initialized here if
> > 128b/132b are?)
> I agree, 8b/10 are the default, but in case where we switch from 
> 128b/132 -> 8b/10b we should be updating them here aswell.
> > > +
> > > +       DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
> > > +                       (link_coding_cap == DP_CAP_ANSI_128B132B) ?
> > > "128b/132b":"8b/10b", mst_state->mgr);
> > > +}
> > > +EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
> > > +
> > >   /**
> > >    * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
> > >    * @mgr: manager for this port
> > > @@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >   
> > >         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
> > >         if (ret) {
> > > -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > > max=63 ret=%d\n",
> > > -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> > > +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d
> > > max=%d ret=%d\n",
> > > +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> > > >total_avail_slots, ret);
> > >                 drm_dp_mst_topology_put_port(port);
> > >                 goto out;
> > >         }
> > > @@ -5226,7 +5238,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >                                          struct
> > > drm_dp_mst_topology_state *mst_state)
> > >   {
> > >         struct drm_dp_vcpi_allocation *vcpi;
> > > -       int avail_slots = 63, payload_count = 0;
> > > +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
> > >   
> > >         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
> > >                 /* Releasing VCPI is always OK-even if the port is gone
> > > */
> > > @@ -5255,7 +5267,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >                 }
> > >         }
> > >         drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI
> > > avail=%d used=%d\n",
> > > -                      mgr, mst_state, avail_slots, 63 - avail_slots);
> > > +                      mgr, mst_state, avail_slots, mgr-
> > > >total_avail_slots - avail_slots);
> > >   
> > >         return 0;
> > >   }
> > > @@ -5421,6 +5433,10 @@ int drm_dp_mst_atomic_check(struct
> > > drm_atomic_state *state)
> > >                         break;
> > >   
> > >                 mutex_lock(&mgr->lock);
> > > +
> > > +               mgr->start_slot = mst_state->start_slot;
> > > +               mgr->total_avail_slots = mst_state->total_avail_slots;
> > > +
> > It feels wrong to me to be copying stuff from mst_state to mgr in
> > general, and in atomic check hook in particular.
> previously we were setting it directly in the mgr, and this was 
> suggested by lyude. I am not sure what the alternative is.
> > >                 ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-
> > > >mst_primary,
> > >                                                             mst_state);
> > >                 mutex_unlock(&mgr->lock);
> > > @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >         if (!mgr->proposed_vcpis)
> > >                 return -ENOMEM;
> > >         set_bit(0, &mgr->payload_mask);
> > > +       mgr->total_avail_slots = 63;
> > > +       mgr->start_slot = 1;
> > >   
> > >         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
> > >         if (mst_state == NULL)
> > >                 return -ENOMEM;
> > >   
> > > +       mst_state->total_avail_slots = 63;
> > > +       mst_state->start_slot = 1;
> > > +
> > The magic values for 8b/10b are now duplicated to two places, with the
> > 128b/132b values in a separate place.
> 
> 8b/10b is the default (to make sure we don't break any existing driver 
> that doesn't use 128b/132b). Are you against setting it as the default 
> here? or do you mean we should use #define for this? the magic numbers 
> are currently being used directly right now (inside 
> drm_dp_find_vcpi_slots, drm_dp_init_vcpi).
> 
> Bhawan
> 
> > BR,
> > Jani.
> > 
> > >         mst_state->mgr = mgr;
> > >         INIT_LIST_HEAD(&mst_state->vcpis);
> > >   
> > > diff --git a/include/drm/drm_dp_mst_helper.h
> > > b/include/drm/drm_dp_mst_helper.h
> > > index ddb9231d0309..f8152dfb34ed 100644
> > > --- a/include/drm/drm_dp_mst_helper.h
> > > +++ b/include/drm/drm_dp_mst_helper.h
> > > @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
> > >         struct drm_private_state base;
> > >         struct list_head vcpis;
> > >         struct drm_dp_mst_topology_mgr *mgr;
> > > +       u8 total_avail_slots;
> > > +       u8 start_slot;
> > >   };
> > >   
> > >   #define to_dp_mst_topology_mgr(x) container_of(x, struct
> > > drm_dp_mst_topology_mgr, base)
> > > @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
> > >          */
> > >         int pbn_div;
> > >   
> > > +       /**
> > > +        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
> > > +        */
> > > +       u8 total_avail_slots;
> > > +
> > > +       /**
> > > +        * @start_slot: 1 for 8b/10b, 0 for 128/132b
> > > +        */
> > > +       u8 start_slot;
> > > +
> > >         /**
> > >          * @funcs: Atomic helper callbacks
> > >          */
> > > @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct
> > > drm_dp_mst_topology_mgr *mgr, struct drm_dp
> > >   
> > >   void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
> > > struct drm_dp_mst_port *port);
> > >   
> > > +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
> > > *mst_state, uint8_t link_coding_cap);
> > >   
> > >   void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
> > >                                 struct drm_dp_mst_port *port);
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-12 21:58         ` [PATCH] " Bhawanpreet Lakha
@ 2021-10-13 21:54             ` kernel test robot
  2021-10-13 16:09           ` Jani Nikula
                               ` (3 subsequent siblings)
  4 siblings, 0 replies; 37+ messages in thread
From: kernel test robot @ 2021-10-13 21:54 UTC (permalink / raw)
  To: Bhawanpreet Lakha, Jerry.Zuo, dri-devel, lyude
  Cc: llvm, kbuild-all, Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas,
	Bhawanpreet Lakha

[-- Attachment #1: Type: text/plain, Size: 16467 bytes --]

Hi Bhawanpreet,

Thank you for the patch! Yet something to improve:

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

url:    https://github.com/0day-ci/linux/commits/Bhawanpreet-Lakha/drm-Update-MST-First-Link-Slot-Information-Based-on-Encoding-Format/20211013-060001
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: x86_64-randconfig-a005-20211013 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project b6a8c695542b2987eb9a203d5663a0740cb4725f)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/5604bf980dcbfdd7650b7e1d5d4a2fd9f18cd866
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Bhawanpreet-Lakha/drm-Update-MST-First-Link-Slot-Information-Based-on-Encoding-Format/20211013-060001
        git checkout 5604bf980dcbfdd7650b7e1d5d4a2fd9f18cd866
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:35:
   In file included from drivers/gpu/drm/amd/amdgpu/../display/dmub/dmub_srv.h:67:
   drivers/gpu/drm/amd/amdgpu/../display/dmub/inc/dmub_cmd.h:2819:12: warning: variable 'temp' set but not used [-Wunused-but-set-variable]
                   uint64_t temp;
                            ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:633:6: warning: no previous prototype for function 'dmub_aux_setconfig_callback' [-Wmissing-prototypes]
   void dmub_aux_setconfig_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
        ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:633:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void dmub_aux_setconfig_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
   ^
   static 
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:649:6: warning: no previous prototype for function 'dmub_hpd_callback' [-Wmissing-prototypes]
   void dmub_hpd_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
        ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:649:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void dmub_hpd_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
   ^
   static 
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:706:6: warning: no previous prototype for function 'register_dmub_notify_callback' [-Wmissing-prototypes]
   bool register_dmub_notify_callback(struct amdgpu_device *adev, enum dmub_notification_type type,
        ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:706:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   bool register_dmub_notify_callback(struct amdgpu_device *adev, enum dmub_notification_type type,
   ^
   static 
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:7174:12: warning: variable 'clock' set but not used [-Wunused-but-set-variable]
           int i, j, clock;
                     ^
>> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:10912:23: error: implicit declaration of function 'dc_link_dp_mst_decide_link_encoding_format' [-Werror,-Wimplicit-function-declaration]
                                   link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
                                                     ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:11394:5: warning: no previous prototype for function 'amdgpu_dm_set_dmub_async_sync_status' [-Wmissing-prototypes]
   int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux, struct dc_context *ctx,
       ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:11394:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux, struct dc_context *ctx,
   ^
   static 
   6 warnings and 1 error generated.


vim +/dc_link_dp_mst_decide_link_encoding_format +10912 drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c

 10643	
 10644	/**
 10645	 * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
 10646	 * @dev: The DRM device
 10647	 * @state: The atomic state to commit
 10648	 *
 10649	 * Validate that the given atomic state is programmable by DC into hardware.
 10650	 * This involves constructing a &struct dc_state reflecting the new hardware
 10651	 * state we wish to commit, then querying DC to see if it is programmable. It's
 10652	 * important not to modify the existing DC state. Otherwise, atomic_check
 10653	 * may unexpectedly commit hardware changes.
 10654	 *
 10655	 * When validating the DC state, it's important that the right locks are
 10656	 * acquired. For full updates case which removes/adds/updates streams on one
 10657	 * CRTC while flipping on another CRTC, acquiring global lock will guarantee
 10658	 * that any such full update commit will wait for completion of any outstanding
 10659	 * flip using DRMs synchronization events.
 10660	 *
 10661	 * Note that DM adds the affected connectors for all CRTCs in state, when that
 10662	 * might not seem necessary. This is because DC stream creation requires the
 10663	 * DC sink, which is tied to the DRM connector state. Cleaning this up should
 10664	 * be possible but non-trivial - a possible TODO item.
 10665	 *
 10666	 * Return: -Error code if validation failed.
 10667	 */
 10668	static int amdgpu_dm_atomic_check(struct drm_device *dev,
 10669					  struct drm_atomic_state *state)
 10670	{
 10671		struct amdgpu_device *adev = drm_to_adev(dev);
 10672		struct dm_atomic_state *dm_state = NULL;
 10673		struct dc *dc = adev->dm.dc;
 10674		struct drm_connector *connector;
 10675		struct drm_connector_state *old_con_state, *new_con_state;
 10676		struct drm_crtc *crtc;
 10677		struct drm_crtc_state *old_crtc_state, *new_crtc_state;
 10678		struct drm_plane *plane;
 10679		struct drm_plane_state *old_plane_state, *new_plane_state;
 10680		enum dc_status status;
 10681		int ret, i;
 10682		bool lock_and_validation_needed = false;
 10683		struct dm_crtc_state *dm_old_crtc_state;
 10684	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10685		struct dsc_mst_fairness_vars vars[MAX_PIPES];
 10686	#endif
 10687		struct drm_dp_mst_topology_state *mst_state;
 10688		struct drm_dp_mst_topology_mgr *mgr;
 10689	
 10690		trace_amdgpu_dm_atomic_check_begin(state);
 10691	
 10692		ret = drm_atomic_helper_check_modeset(dev, state);
 10693		if (ret)
 10694			goto fail;
 10695	
 10696		/* Check connector changes */
 10697		for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
 10698			struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
 10699			struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 10700	
 10701			/* Skip connectors that are disabled or part of modeset already. */
 10702			if (!old_con_state->crtc && !new_con_state->crtc)
 10703				continue;
 10704	
 10705			if (!new_con_state->crtc)
 10706				continue;
 10707	
 10708			new_crtc_state = drm_atomic_get_crtc_state(state, new_con_state->crtc);
 10709			if (IS_ERR(new_crtc_state)) {
 10710				ret = PTR_ERR(new_crtc_state);
 10711				goto fail;
 10712			}
 10713	
 10714			if (dm_old_con_state->abm_level !=
 10715			    dm_new_con_state->abm_level)
 10716				new_crtc_state->connectors_changed = true;
 10717		}
 10718	
 10719	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10720		if (dc_resource_is_dsc_encoding_supported(dc)) {
 10721			for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10722				if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
 10723					ret = add_affected_mst_dsc_crtcs(state, crtc);
 10724					if (ret)
 10725						goto fail;
 10726				}
 10727			}
 10728		}
 10729	#endif
 10730		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10731			dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
 10732	
 10733			if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
 10734			    !new_crtc_state->color_mgmt_changed &&
 10735			    old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled &&
 10736				dm_old_crtc_state->dsc_force_changed == false)
 10737				continue;
 10738	
 10739			ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);
 10740			if (ret)
 10741				goto fail;
 10742	
 10743			if (!new_crtc_state->enable)
 10744				continue;
 10745	
 10746			ret = drm_atomic_add_affected_connectors(state, crtc);
 10747			if (ret)
 10748				return ret;
 10749	
 10750			ret = drm_atomic_add_affected_planes(state, crtc);
 10751			if (ret)
 10752				goto fail;
 10753	
 10754			if (dm_old_crtc_state->dsc_force_changed)
 10755				new_crtc_state->mode_changed = true;
 10756		}
 10757	
 10758		/*
 10759		 * Add all primary and overlay planes on the CRTC to the state
 10760		 * whenever a plane is enabled to maintain correct z-ordering
 10761		 * and to enable fast surface updates.
 10762		 */
 10763		drm_for_each_crtc(crtc, dev) {
 10764			bool modified = false;
 10765	
 10766			for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
 10767				if (plane->type == DRM_PLANE_TYPE_CURSOR)
 10768					continue;
 10769	
 10770				if (new_plane_state->crtc == crtc ||
 10771				    old_plane_state->crtc == crtc) {
 10772					modified = true;
 10773					break;
 10774				}
 10775			}
 10776	
 10777			if (!modified)
 10778				continue;
 10779	
 10780			drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) {
 10781				if (plane->type == DRM_PLANE_TYPE_CURSOR)
 10782					continue;
 10783	
 10784				new_plane_state =
 10785					drm_atomic_get_plane_state(state, plane);
 10786	
 10787				if (IS_ERR(new_plane_state)) {
 10788					ret = PTR_ERR(new_plane_state);
 10789					goto fail;
 10790				}
 10791			}
 10792		}
 10793	
 10794		/* Remove exiting planes if they are modified */
 10795		for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
 10796			ret = dm_update_plane_state(dc, state, plane,
 10797						    old_plane_state,
 10798						    new_plane_state,
 10799						    false,
 10800						    &lock_and_validation_needed);
 10801			if (ret)
 10802				goto fail;
 10803		}
 10804	
 10805		/* Disable all crtcs which require disable */
 10806		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10807			ret = dm_update_crtc_state(&adev->dm, state, crtc,
 10808						   old_crtc_state,
 10809						   new_crtc_state,
 10810						   false,
 10811						   &lock_and_validation_needed);
 10812			if (ret)
 10813				goto fail;
 10814		}
 10815	
 10816		/* Enable all crtcs which require enable */
 10817		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10818			ret = dm_update_crtc_state(&adev->dm, state, crtc,
 10819						   old_crtc_state,
 10820						   new_crtc_state,
 10821						   true,
 10822						   &lock_and_validation_needed);
 10823			if (ret)
 10824				goto fail;
 10825		}
 10826	
 10827		ret = validate_overlay(state);
 10828		if (ret)
 10829			goto fail;
 10830	
 10831		/* Add new/modified planes */
 10832		for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
 10833			ret = dm_update_plane_state(dc, state, plane,
 10834						    old_plane_state,
 10835						    new_plane_state,
 10836						    true,
 10837						    &lock_and_validation_needed);
 10838			if (ret)
 10839				goto fail;
 10840		}
 10841	
 10842		/* Run this here since we want to validate the streams we created */
 10843		ret = drm_atomic_helper_check_planes(dev, state);
 10844		if (ret)
 10845			goto fail;
 10846	
 10847		/* Check cursor planes scaling */
 10848		for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
 10849			ret = dm_check_crtc_cursor(state, crtc, new_crtc_state);
 10850			if (ret)
 10851				goto fail;
 10852		}
 10853	
 10854		if (state->legacy_cursor_update) {
 10855			/*
 10856			 * This is a fast cursor update coming from the plane update
 10857			 * helper, check if it can be done asynchronously for better
 10858			 * performance.
 10859			 */
 10860			state->async_update =
 10861				!drm_atomic_helper_async_check(dev, state);
 10862	
 10863			/*
 10864			 * Skip the remaining global validation if this is an async
 10865			 * update. Cursor updates can be done without affecting
 10866			 * state or bandwidth calcs and this avoids the performance
 10867			 * penalty of locking the private state object and
 10868			 * allocating a new dc_state.
 10869			 */
 10870			if (state->async_update)
 10871				return 0;
 10872		}
 10873	
 10874		/* Check scaling and underscan changes*/
 10875		/* TODO Removed scaling changes validation due to inability to commit
 10876		 * new stream into context w\o causing full reset. Need to
 10877		 * decide how to handle.
 10878		 */
 10879		for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
 10880			struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
 10881			struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 10882			struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
 10883	
 10884			/* Skip any modesets/resets */
 10885			if (!acrtc || drm_atomic_crtc_needs_modeset(
 10886					drm_atomic_get_new_crtc_state(state, &acrtc->base)))
 10887				continue;
 10888	
 10889			/* Skip any thing not scale or underscan changes */
 10890			if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state))
 10891				continue;
 10892	
 10893			lock_and_validation_needed = true;
 10894		}
 10895	
 10896	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10897		for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
 10898			struct amdgpu_dm_connector *aconnector;
 10899			struct drm_connector *connector;
 10900			struct drm_connector_list_iter iter;
 10901			u8 link_coding_cap;
 10902	
 10903			if (!mgr->mst_state )
 10904				continue;
 10905	
 10906			drm_connector_list_iter_begin(dev, &iter);
 10907			drm_for_each_connector_iter(connector, &iter) {
 10908				int id = connector->index;
 10909	
 10910				if (id == mst_state->mgr->conn_base_id) {
 10911					aconnector = to_amdgpu_dm_connector(connector);
 10912					link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
 10913					drm_dp_mst_update_coding_cap(mst_state, link_coding_cap);
 10914	
 10915					break;
 10916				}
 10917			}
 10918			drm_connector_list_iter_end(&iter);
 10919	
 10920		}
 10921	#endif
 10922		/**
 10923		 * Streams and planes are reset when there are changes that affect
 10924		 * bandwidth. Anything that affects bandwidth needs to go through
 10925		 * DC global validation to ensure that the configuration can be applied
 10926		 * to hardware.
 10927		 *
 10928		 * We have to currently stall out here in atomic_check for outstanding
 10929		 * commits to finish in this case because our IRQ handlers reference
 10930		 * DRM state directly - we can end up disabling interrupts too early
 10931		 * if we don't.
 10932		 *
 10933		 * TODO: Remove this stall and drop DM state private objects.
 10934		 */
 10935		if (lock_and_validation_needed) {
 10936			ret = dm_atomic_get_state(state, &dm_state);
 10937			if (ret)
 10938				goto fail;
 10939	
 10940			ret = do_aquire_global_lock(dev, state);
 10941			if (ret)
 10942				goto fail;
 10943	

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 39870 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
@ 2021-10-13 21:54             ` kernel test robot
  0 siblings, 0 replies; 37+ messages in thread
From: kernel test robot @ 2021-10-13 21:54 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 16848 bytes --]

Hi Bhawanpreet,

Thank you for the patch! Yet something to improve:

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

url:    https://github.com/0day-ci/linux/commits/Bhawanpreet-Lakha/drm-Update-MST-First-Link-Slot-Information-Based-on-Encoding-Format/20211013-060001
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: x86_64-randconfig-a005-20211013 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project b6a8c695542b2987eb9a203d5663a0740cb4725f)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/5604bf980dcbfdd7650b7e1d5d4a2fd9f18cd866
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Bhawanpreet-Lakha/drm-Update-MST-First-Link-Slot-Information-Based-on-Encoding-Format/20211013-060001
        git checkout 5604bf980dcbfdd7650b7e1d5d4a2fd9f18cd866
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:35:
   In file included from drivers/gpu/drm/amd/amdgpu/../display/dmub/dmub_srv.h:67:
   drivers/gpu/drm/amd/amdgpu/../display/dmub/inc/dmub_cmd.h:2819:12: warning: variable 'temp' set but not used [-Wunused-but-set-variable]
                   uint64_t temp;
                            ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:633:6: warning: no previous prototype for function 'dmub_aux_setconfig_callback' [-Wmissing-prototypes]
   void dmub_aux_setconfig_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
        ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:633:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void dmub_aux_setconfig_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
   ^
   static 
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:649:6: warning: no previous prototype for function 'dmub_hpd_callback' [-Wmissing-prototypes]
   void dmub_hpd_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
        ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:649:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void dmub_hpd_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
   ^
   static 
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:706:6: warning: no previous prototype for function 'register_dmub_notify_callback' [-Wmissing-prototypes]
   bool register_dmub_notify_callback(struct amdgpu_device *adev, enum dmub_notification_type type,
        ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:706:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   bool register_dmub_notify_callback(struct amdgpu_device *adev, enum dmub_notification_type type,
   ^
   static 
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:7174:12: warning: variable 'clock' set but not used [-Wunused-but-set-variable]
           int i, j, clock;
                     ^
>> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:10912:23: error: implicit declaration of function 'dc_link_dp_mst_decide_link_encoding_format' [-Werror,-Wimplicit-function-declaration]
                                   link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
                                                     ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:11394:5: warning: no previous prototype for function 'amdgpu_dm_set_dmub_async_sync_status' [-Wmissing-prototypes]
   int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux, struct dc_context *ctx,
       ^
   drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:11394:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux, struct dc_context *ctx,
   ^
   static 
   6 warnings and 1 error generated.


vim +/dc_link_dp_mst_decide_link_encoding_format +10912 drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c

 10643	
 10644	/**
 10645	 * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
 10646	 * @dev: The DRM device
 10647	 * @state: The atomic state to commit
 10648	 *
 10649	 * Validate that the given atomic state is programmable by DC into hardware.
 10650	 * This involves constructing a &struct dc_state reflecting the new hardware
 10651	 * state we wish to commit, then querying DC to see if it is programmable. It's
 10652	 * important not to modify the existing DC state. Otherwise, atomic_check
 10653	 * may unexpectedly commit hardware changes.
 10654	 *
 10655	 * When validating the DC state, it's important that the right locks are
 10656	 * acquired. For full updates case which removes/adds/updates streams on one
 10657	 * CRTC while flipping on another CRTC, acquiring global lock will guarantee
 10658	 * that any such full update commit will wait for completion of any outstanding
 10659	 * flip using DRMs synchronization events.
 10660	 *
 10661	 * Note that DM adds the affected connectors for all CRTCs in state, when that
 10662	 * might not seem necessary. This is because DC stream creation requires the
 10663	 * DC sink, which is tied to the DRM connector state. Cleaning this up should
 10664	 * be possible but non-trivial - a possible TODO item.
 10665	 *
 10666	 * Return: -Error code if validation failed.
 10667	 */
 10668	static int amdgpu_dm_atomic_check(struct drm_device *dev,
 10669					  struct drm_atomic_state *state)
 10670	{
 10671		struct amdgpu_device *adev = drm_to_adev(dev);
 10672		struct dm_atomic_state *dm_state = NULL;
 10673		struct dc *dc = adev->dm.dc;
 10674		struct drm_connector *connector;
 10675		struct drm_connector_state *old_con_state, *new_con_state;
 10676		struct drm_crtc *crtc;
 10677		struct drm_crtc_state *old_crtc_state, *new_crtc_state;
 10678		struct drm_plane *plane;
 10679		struct drm_plane_state *old_plane_state, *new_plane_state;
 10680		enum dc_status status;
 10681		int ret, i;
 10682		bool lock_and_validation_needed = false;
 10683		struct dm_crtc_state *dm_old_crtc_state;
 10684	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10685		struct dsc_mst_fairness_vars vars[MAX_PIPES];
 10686	#endif
 10687		struct drm_dp_mst_topology_state *mst_state;
 10688		struct drm_dp_mst_topology_mgr *mgr;
 10689	
 10690		trace_amdgpu_dm_atomic_check_begin(state);
 10691	
 10692		ret = drm_atomic_helper_check_modeset(dev, state);
 10693		if (ret)
 10694			goto fail;
 10695	
 10696		/* Check connector changes */
 10697		for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
 10698			struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
 10699			struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 10700	
 10701			/* Skip connectors that are disabled or part of modeset already. */
 10702			if (!old_con_state->crtc && !new_con_state->crtc)
 10703				continue;
 10704	
 10705			if (!new_con_state->crtc)
 10706				continue;
 10707	
 10708			new_crtc_state = drm_atomic_get_crtc_state(state, new_con_state->crtc);
 10709			if (IS_ERR(new_crtc_state)) {
 10710				ret = PTR_ERR(new_crtc_state);
 10711				goto fail;
 10712			}
 10713	
 10714			if (dm_old_con_state->abm_level !=
 10715			    dm_new_con_state->abm_level)
 10716				new_crtc_state->connectors_changed = true;
 10717		}
 10718	
 10719	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10720		if (dc_resource_is_dsc_encoding_supported(dc)) {
 10721			for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10722				if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
 10723					ret = add_affected_mst_dsc_crtcs(state, crtc);
 10724					if (ret)
 10725						goto fail;
 10726				}
 10727			}
 10728		}
 10729	#endif
 10730		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10731			dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
 10732	
 10733			if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
 10734			    !new_crtc_state->color_mgmt_changed &&
 10735			    old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled &&
 10736				dm_old_crtc_state->dsc_force_changed == false)
 10737				continue;
 10738	
 10739			ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);
 10740			if (ret)
 10741				goto fail;
 10742	
 10743			if (!new_crtc_state->enable)
 10744				continue;
 10745	
 10746			ret = drm_atomic_add_affected_connectors(state, crtc);
 10747			if (ret)
 10748				return ret;
 10749	
 10750			ret = drm_atomic_add_affected_planes(state, crtc);
 10751			if (ret)
 10752				goto fail;
 10753	
 10754			if (dm_old_crtc_state->dsc_force_changed)
 10755				new_crtc_state->mode_changed = true;
 10756		}
 10757	
 10758		/*
 10759		 * Add all primary and overlay planes on the CRTC to the state
 10760		 * whenever a plane is enabled to maintain correct z-ordering
 10761		 * and to enable fast surface updates.
 10762		 */
 10763		drm_for_each_crtc(crtc, dev) {
 10764			bool modified = false;
 10765	
 10766			for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
 10767				if (plane->type == DRM_PLANE_TYPE_CURSOR)
 10768					continue;
 10769	
 10770				if (new_plane_state->crtc == crtc ||
 10771				    old_plane_state->crtc == crtc) {
 10772					modified = true;
 10773					break;
 10774				}
 10775			}
 10776	
 10777			if (!modified)
 10778				continue;
 10779	
 10780			drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) {
 10781				if (plane->type == DRM_PLANE_TYPE_CURSOR)
 10782					continue;
 10783	
 10784				new_plane_state =
 10785					drm_atomic_get_plane_state(state, plane);
 10786	
 10787				if (IS_ERR(new_plane_state)) {
 10788					ret = PTR_ERR(new_plane_state);
 10789					goto fail;
 10790				}
 10791			}
 10792		}
 10793	
 10794		/* Remove exiting planes if they are modified */
 10795		for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
 10796			ret = dm_update_plane_state(dc, state, plane,
 10797						    old_plane_state,
 10798						    new_plane_state,
 10799						    false,
 10800						    &lock_and_validation_needed);
 10801			if (ret)
 10802				goto fail;
 10803		}
 10804	
 10805		/* Disable all crtcs which require disable */
 10806		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10807			ret = dm_update_crtc_state(&adev->dm, state, crtc,
 10808						   old_crtc_state,
 10809						   new_crtc_state,
 10810						   false,
 10811						   &lock_and_validation_needed);
 10812			if (ret)
 10813				goto fail;
 10814		}
 10815	
 10816		/* Enable all crtcs which require enable */
 10817		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 10818			ret = dm_update_crtc_state(&adev->dm, state, crtc,
 10819						   old_crtc_state,
 10820						   new_crtc_state,
 10821						   true,
 10822						   &lock_and_validation_needed);
 10823			if (ret)
 10824				goto fail;
 10825		}
 10826	
 10827		ret = validate_overlay(state);
 10828		if (ret)
 10829			goto fail;
 10830	
 10831		/* Add new/modified planes */
 10832		for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
 10833			ret = dm_update_plane_state(dc, state, plane,
 10834						    old_plane_state,
 10835						    new_plane_state,
 10836						    true,
 10837						    &lock_and_validation_needed);
 10838			if (ret)
 10839				goto fail;
 10840		}
 10841	
 10842		/* Run this here since we want to validate the streams we created */
 10843		ret = drm_atomic_helper_check_planes(dev, state);
 10844		if (ret)
 10845			goto fail;
 10846	
 10847		/* Check cursor planes scaling */
 10848		for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
 10849			ret = dm_check_crtc_cursor(state, crtc, new_crtc_state);
 10850			if (ret)
 10851				goto fail;
 10852		}
 10853	
 10854		if (state->legacy_cursor_update) {
 10855			/*
 10856			 * This is a fast cursor update coming from the plane update
 10857			 * helper, check if it can be done asynchronously for better
 10858			 * performance.
 10859			 */
 10860			state->async_update =
 10861				!drm_atomic_helper_async_check(dev, state);
 10862	
 10863			/*
 10864			 * Skip the remaining global validation if this is an async
 10865			 * update. Cursor updates can be done without affecting
 10866			 * state or bandwidth calcs and this avoids the performance
 10867			 * penalty of locking the private state object and
 10868			 * allocating a new dc_state.
 10869			 */
 10870			if (state->async_update)
 10871				return 0;
 10872		}
 10873	
 10874		/* Check scaling and underscan changes*/
 10875		/* TODO Removed scaling changes validation due to inability to commit
 10876		 * new stream into context w\o causing full reset. Need to
 10877		 * decide how to handle.
 10878		 */
 10879		for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
 10880			struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
 10881			struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 10882			struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
 10883	
 10884			/* Skip any modesets/resets */
 10885			if (!acrtc || drm_atomic_crtc_needs_modeset(
 10886					drm_atomic_get_new_crtc_state(state, &acrtc->base)))
 10887				continue;
 10888	
 10889			/* Skip any thing not scale or underscan changes */
 10890			if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state))
 10891				continue;
 10892	
 10893			lock_and_validation_needed = true;
 10894		}
 10895	
 10896	#if defined(CONFIG_DRM_AMD_DC_DCN)
 10897		for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
 10898			struct amdgpu_dm_connector *aconnector;
 10899			struct drm_connector *connector;
 10900			struct drm_connector_list_iter iter;
 10901			u8 link_coding_cap;
 10902	
 10903			if (!mgr->mst_state )
 10904				continue;
 10905	
 10906			drm_connector_list_iter_begin(dev, &iter);
 10907			drm_for_each_connector_iter(connector, &iter) {
 10908				int id = connector->index;
 10909	
 10910				if (id == mst_state->mgr->conn_base_id) {
 10911					aconnector = to_amdgpu_dm_connector(connector);
 10912					link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
 10913					drm_dp_mst_update_coding_cap(mst_state, link_coding_cap);
 10914	
 10915					break;
 10916				}
 10917			}
 10918			drm_connector_list_iter_end(&iter);
 10919	
 10920		}
 10921	#endif
 10922		/**
 10923		 * Streams and planes are reset when there are changes that affect
 10924		 * bandwidth. Anything that affects bandwidth needs to go through
 10925		 * DC global validation to ensure that the configuration can be applied
 10926		 * to hardware.
 10927		 *
 10928		 * We have to currently stall out here in atomic_check for outstanding
 10929		 * commits to finish in this case because our IRQ handlers reference
 10930		 * DRM state directly - we can end up disabling interrupts too early
 10931		 * if we don't.
 10932		 *
 10933		 * TODO: Remove this stall and drop DM state private objects.
 10934		 */
 10935		if (lock_and_validation_needed) {
 10936			ret = dm_atomic_get_state(state, &dm_state);
 10937			if (ret)
 10938				goto fail;
 10939	
 10940			ret = do_aquire_global_lock(dev, state);
 10941			if (ret)
 10942				goto fail;
 10943	

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

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 39870 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-12 21:58         ` [PATCH] " Bhawanpreet Lakha
                             ` (3 preceding siblings ...)
  2021-10-13 21:54             ` kernel test robot
@ 2021-10-13 22:25           ` Lyude Paul
  2021-10-14 20:21             ` Bhawanpreet Lakha
  2021-10-15 19:43             ` Bhawanpreet Lakha
  4 siblings, 2 replies; 37+ messages in thread
From: Lyude Paul @ 2021-10-13 22:25 UTC (permalink / raw)
  To: Bhawanpreet Lakha, Jerry.Zuo, dri-devel
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas

Some comments below (also, sorry again for the mixup on the last review!)

On Tue, 2021-10-12 at 17:58 -0400, Bhawanpreet Lakha wrote:
> 8b/10b encoding format requires to reserve the first slot for
> recording metadata. Real data transmission starts from the second slot,
> with a total of available 63 slots available.
> 
> In 128b/132b encoding format, metadata is transmitted separately
> in LLCP packet before MTP. Real data transmission starts from
> the first slot, with a total of 64 slots available.
> 
> v2:
> * Remove get_mst_link_encoding_cap
> * Move total/start slots to mst_state, and copy it to mst_mgr in
> atomic_check
> 
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++++++
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 35 +++++++++++++++----
>  include/drm/drm_dp_mst_helper.h               | 13 +++++++
>  3 files changed, 69 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 5020f2d36fe1..4ad50eb0091a 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -10612,6 +10612,8 @@ static int amdgpu_dm_atomic_check(struct drm_device
> *dev,
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
>         struct dsc_mst_fairness_vars vars[MAX_PIPES];
>  #endif
> +       struct drm_dp_mst_topology_state *mst_state;
> +       struct drm_dp_mst_topology_mgr *mgr;
>  
>         trace_amdgpu_dm_atomic_check_begin(state);
>  
> @@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device
> *dev,
>                 lock_and_validation_needed = true;
>         }
>  
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
> +               struct amdgpu_dm_connector *aconnector;
> +               struct drm_connector *connector;
> +               struct drm_connector_list_iter iter;
> +               u8 link_coding_cap;
> +
> +               if (!mgr->mst_state )
> +                       continue;

extraneous space

> +
> +               drm_connector_list_iter_begin(dev, &iter);
> +               drm_for_each_connector_iter(connector, &iter) {
> +                       int id = connector->index;
> +
> +                       if (id == mst_state->mgr->conn_base_id) {
> +                               aconnector =
> to_amdgpu_dm_connector(connector);
> +                               link_coding_cap =
> dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
> +                               drm_dp_mst_update_coding_cap(mst_state,
> link_coding_cap);
> +
> +                               break;
> +                       }
> +               }
> +               drm_connector_list_iter_end(&iter);
> +
> +       }
> +#endif
>         /**
>          * Streams and planes are reset when there are changes that affect
>          * bandwidth. Anything that affects bandwidth needs to go through
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index ad0795afc21c..fb5c47c4cb2e 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct
> drm_dp_mst_topology_mgr *mgr)
>         struct drm_dp_payload req_payload;
>         struct drm_dp_mst_port *port;
>         int i, j;
> -       int cur_slots = 1;
> +       int cur_slots = mgr->start_slot;
>         bool skip;
>  
>         mutex_lock(&mgr->payload_lock);
> @@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct
> drm_dp_mst_topology_mgr *mgr,
>         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
>  
>         /* max. time slots - one slot for MTP header */
> -       if (num_slots > 63)
> +       if (num_slots > mgr->total_avail_slots)
>                 return -ENOSPC;

For reasons I will explain a little further in this email, we might want to
drop this…

>         return num_slots;
>  }
> @@ -4333,7 +4333,7 @@ static int drm_dp_init_vcpi(struct
> drm_dp_mst_topology_mgr *mgr,
>         int ret;
>  
>         /* max. time slots - one slot for MTP header */
> -       if (slots > 63)
> +       if (slots > mgr->total_avail_slots)

…and this

>                 return -ENOSPC;
>  
>         vcpi->pbn = pbn;
> @@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct
> drm_atomic_state *state,
>  }
>  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>  
> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
> *mst_state, uint8_t link_coding_cap)

Need some kdocs here

> +{
> +       if (link_coding_cap == DP_CAP_ANSI_128B132B) {
> +               mst_state->total_avail_slots = 64;
> +               mst_state->start_slot = 0;
> +       }
> +
> +       DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
> +                       (link_coding_cap == DP_CAP_ANSI_128B132B) ?
> "128b/132b":"8b/10b", mst_state->mgr);

need to fix indenting here, and wrap this to 100 chars

> +}
> +EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
> +
>  /**
>   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>   * @mgr: manager for this port
> @@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> drm_dp_mst_topology_mgr *mgr,
>  
>         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
>         if (ret) {
> -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63
> ret=%d\n",
> -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=%d
> ret=%d\n",
> +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> >total_avail_slots, ret);
>                 drm_dp_mst_topology_put_port(port);
>                 goto out;
>         }
> @@ -5226,7 +5238,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> drm_dp_mst_topology_mgr *mgr,
>                                          struct drm_dp_mst_topology_state
> *mst_state)
>  {
>         struct drm_dp_vcpi_allocation *vcpi;
> -       int avail_slots = 63, payload_count = 0;
> +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
>  
>         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>                 /* Releasing VCPI is always OK-even if the port is gone */
> @@ -5255,7 +5267,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> drm_dp_mst_topology_mgr *mgr,
>                 }
>         }
>         drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d
> used=%d\n",
> -                      mgr, mst_state, avail_slots, 63 - avail_slots);
> +                      mgr, mst_state, avail_slots, mgr->total_avail_slots -
> avail_slots);
>  
>         return 0;
>  }
> @@ -5421,6 +5433,10 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state
> *state)
>                         break;
>  
>                 mutex_lock(&mgr->lock);
> +
> +               mgr->start_slot = mst_state->start_slot;
> +               mgr->total_avail_slots = mst_state->total_avail_slots;
> +

this isn't correct - atomic checks aren't allowed to mutate anything besides
the atomic state structure that we're checking since we don't know whether or
not the display state is going to be committed when checking it. If we're
storing state in mgr, that state needs to be written to mgr during the atomic
commit instead of the atomic check.

...but, coming back to this MST code after being gone for a while, I think it
might be time for us to stop worrying about the non-atomic state. Especially
since there's only one driver using it; the legacy radeon.ko; and right now
the plan is either to just drop MST support on radeon.ko or move the MST code
it uses into radeon.ko.Which brings me to say - I think we can drop some of
the hunks I mentioned above (e.g. the changes to drm_dp_init_vcpi and
drm_dp_find_vcpi_slots I mentioned above). We can then just update the kdocs
for these functions in a separate patch to clarify that now in addition to
being deprecated, these functions are just broken and will eventually be
removed.

So - doing that allows us to get rid of mgr->total_avail_slots and mgr-
>start_slot entirely, just set the slot info in the atomic state during atomic
check, and then just rely on the atomic state for
drm_dp_atomic_find_vcpi_slots() and friends. Which seems much simpler to me,
does this sound alrght with you?

>                 ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-
> >mst_primary,
>                                                             mst_state);
>                 mutex_unlock(&mgr->lock);
> @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
> drm_dp_mst_topology_mgr *mgr,
>         if (!mgr->proposed_vcpis)
>                 return -ENOMEM;
>         set_bit(0, &mgr->payload_mask);
> +       mgr->total_avail_slots = 63;
> +       mgr->start_slot = 1;
>  
>         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>         if (mst_state == NULL)
>                 return -ENOMEM;
>  
> +       mst_state->total_avail_slots = 63;
> +       mst_state->start_slot = 1;
> +
>         mst_state->mgr = mgr;
>         INIT_LIST_HEAD(&mst_state->vcpis);
>  
> diff --git a/include/drm/drm_dp_mst_helper.h
> b/include/drm/drm_dp_mst_helper.h
> index ddb9231d0309..f8152dfb34ed 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
>         struct drm_private_state base;
>         struct list_head vcpis;
>         struct drm_dp_mst_topology_mgr *mgr;
> +       u8 total_avail_slots;
> +       u8 start_slot;
>  };
>  
>  #define to_dp_mst_topology_mgr(x) container_of(x, struct
> drm_dp_mst_topology_mgr, base)
> @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
>          */
>         int pbn_div;
>  
> +       /**
> +        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
> +        */
> +       u8 total_avail_slots;
> +
> +       /**
> +        * @start_slot: 1 for 8b/10b, 0 for 128/132b
> +        */
> +       u8 start_slot;
> +
>         /**
>          * @funcs: Atomic helper callbacks
>          */
> @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct
> drm_dp_mst_topology_mgr *mgr, struct drm_dp
>  
>  void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
> struct drm_dp_mst_port *port);
>  
> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
> *mst_state, uint8_t link_coding_cap);
>  
>  void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>                                 struct drm_dp_mst_port *port);

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-13 22:25           ` Lyude Paul
@ 2021-10-14 20:21             ` Bhawanpreet Lakha
  2021-10-14 20:22               ` Bhawanpreet Lakha
  2021-10-15 20:04               ` Lyude Paul
  2021-10-15 19:43             ` Bhawanpreet Lakha
  1 sibling, 2 replies; 37+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-14 20:21 UTC (permalink / raw)
  To: Lyude Paul, Jerry.Zuo, dri-devel
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas


On 2021-10-13 6:25 p.m., Lyude Paul wrote:
> Some comments below (also, sorry again for the mixup on the last review!)
>
> On Tue, 2021-10-12 at 17:58 -0400, Bhawanpreet Lakha wrote:
>> 8b/10b encoding format requires to reserve the first slot for
>> recording metadata. Real data transmission starts from the second slot,
>> with a total of available 63 slots available.
>>
>> In 128b/132b encoding format, metadata is transmitted separately
>> in LLCP packet before MTP. Real data transmission starts from
>> the first slot, with a total of 64 slots available.
>>
>> v2:
>> * Remove get_mst_link_encoding_cap
>> * Move total/start slots to mst_state, and copy it to mst_mgr in
>> atomic_check
>>
>> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
>> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
>> ---
>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++++++
>>   drivers/gpu/drm/drm_dp_mst_topology.c         | 35 +++++++++++++++----
>>   include/drm/drm_dp_mst_helper.h               | 13 +++++++
>>   3 files changed, 69 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> index 5020f2d36fe1..4ad50eb0091a 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -10612,6 +10612,8 @@ static int amdgpu_dm_atomic_check(struct drm_device
>> *dev,
>>   #if defined(CONFIG_DRM_AMD_DC_DCN)
>>          struct dsc_mst_fairness_vars vars[MAX_PIPES];
>>   #endif
>> +       struct drm_dp_mst_topology_state *mst_state;
>> +       struct drm_dp_mst_topology_mgr *mgr;
>>   
>>          trace_amdgpu_dm_atomic_check_begin(state);
>>   
>> @@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device
>> *dev,
>>                  lock_and_validation_needed = true;
>>          }
>>   
>> +#if defined(CONFIG_DRM_AMD_DC_DCN)
>> +       for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
>> +               struct amdgpu_dm_connector *aconnector;
>> +               struct drm_connector *connector;
>> +               struct drm_connector_list_iter iter;
>> +               u8 link_coding_cap;
>> +
>> +               if (!mgr->mst_state )
>> +                       continue;
> extraneous space
>
>> +
>> +               drm_connector_list_iter_begin(dev, &iter);
>> +               drm_for_each_connector_iter(connector, &iter) {
>> +                       int id = connector->index;
>> +
>> +                       if (id == mst_state->mgr->conn_base_id) {
>> +                               aconnector =
>> to_amdgpu_dm_connector(connector);
>> +                               link_coding_cap =
>> dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
>> +                               drm_dp_mst_update_coding_cap(mst_state,
>> link_coding_cap);
>> +
>> +                               break;
>> +                       }
>> +               }
>> +               drm_connector_list_iter_end(&iter);
>> +
>> +       }
>> +#endif
>>          /**
>>           * Streams and planes are reset when there are changes that affect
>>           * bandwidth. Anything that affects bandwidth needs to go through
>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>> index ad0795afc21c..fb5c47c4cb2e 100644
>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>> @@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct
>> drm_dp_mst_topology_mgr *mgr)
>>          struct drm_dp_payload req_payload;
>>          struct drm_dp_mst_port *port;
>>          int i, j;
>> -       int cur_slots = 1;
>> +       int cur_slots = mgr->start_slot;
>>          bool skip;
>>   
>>          mutex_lock(&mgr->payload_lock);
>> @@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct
>> drm_dp_mst_topology_mgr *mgr,
>>          num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
>>   
>>          /* max. time slots - one slot for MTP header */
>> -       if (num_slots > 63)
>> +       if (num_slots > mgr->total_avail_slots)
>>                  return -ENOSPC;
> For reasons I will explain a little further in this email, we might want to
> drop this…
>
>>          return num_slots;
>>   }
>> @@ -4333,7 +4333,7 @@ static int drm_dp_init_vcpi(struct
>> drm_dp_mst_topology_mgr *mgr,
>>          int ret;
>>   
>>          /* max. time slots - one slot for MTP header */
>> -       if (slots > 63)
>> +       if (slots > mgr->total_avail_slots)
> …and this
>
>>                  return -ENOSPC;
>>   
>>          vcpi->pbn = pbn;
>> @@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct
>> drm_atomic_state *state,
>>   }
>>   EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>>   
>> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
>> *mst_state, uint8_t link_coding_cap)
> Need some kdocs here
>
>> +{
>> +       if (link_coding_cap == DP_CAP_ANSI_128B132B) {
>> +               mst_state->total_avail_slots = 64;
>> +               mst_state->start_slot = 0;
>> +       }
>> +
>> +       DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
>> +                       (link_coding_cap == DP_CAP_ANSI_128B132B) ?
>> "128b/132b":"8b/10b", mst_state->mgr);
> need to fix indenting here, and wrap this to 100 chars
>
>> +}
>> +EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
>> +
>>   /**
>>    * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>>    * @mgr: manager for this port
>> @@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct
>> drm_dp_mst_topology_mgr *mgr,
>>   
>>          ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
>>          if (ret) {
>> -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63
>> ret=%d\n",
>> -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
>> +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=%d
>> ret=%d\n",
>> +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
>>> total_avail_slots, ret);
>>                  drm_dp_mst_topology_put_port(port);
>>                  goto out;
>>          }
>> @@ -5226,7 +5238,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
>> drm_dp_mst_topology_mgr *mgr,
>>                                           struct drm_dp_mst_topology_state
>> *mst_state)
>>   {
>>          struct drm_dp_vcpi_allocation *vcpi;
>> -       int avail_slots = 63, payload_count = 0;
>> +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
>>   
>>          list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>>                  /* Releasing VCPI is always OK-even if the port is gone */
>> @@ -5255,7 +5267,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
>> drm_dp_mst_topology_mgr *mgr,
>>                  }
>>          }
>>          drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d
>> used=%d\n",
>> -                      mgr, mst_state, avail_slots, 63 - avail_slots);
>> +                      mgr, mst_state, avail_slots, mgr->total_avail_slots -
>> avail_slots);
>>   
>>          return 0;
>>   }
>> @@ -5421,6 +5433,10 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state
>> *state)
>>                          break;
>>   
>>                  mutex_lock(&mgr->lock);
>> +
>> +               mgr->start_slot = mst_state->start_slot;
>> +               mgr->total_avail_slots = mst_state->total_avail_slots;
>> +
> this isn't correct - atomic checks aren't allowed to mutate anything besides
> the atomic state structure that we're checking since we don't know whether or
> not the display state is going to be committed when checking it. If we're
> storing state in mgr, that state needs to be written to mgr during the atomic
> commit instead of the atomic check.
>
> ...but, coming back to this MST code after being gone for a while, I think it
> might be time for us to stop worrying about the non-atomic state. Especially
> since there's only one driver using it; the legacy radeon.ko; and right now
> the plan is either to just drop MST support on radeon.ko or move the MST code
> it uses into radeon.ko.Which brings me to say - I think we can drop some of
> the hunks I mentioned above (e.g. the changes to drm_dp_init_vcpi and
> drm_dp_find_vcpi_slots I mentioned above). We can then just update the kdocs
> for these functions in a separate patch to clarify that now in addition to
> being deprecated, these functions are just broken and will eventually be
> removed.
>
> So - doing that allows us to get rid of mgr->total_avail_slots and mgr-
>> start_slot entirely, just set the slot info in the atomic state during atomic
> check, and then just rely on the atomic state for
> drm_dp_atomic_find_vcpi_slots() and friends. Which seems much simpler to me,
> does this sound alrght with you?

Thanks for the response,

That function is per port (drm_dp_atomic_find_vcpi_slots) so not sure 
how that will work, maybe I don't understand what you mean?

Also we only need to check this inside 
drm_dp_mst_atomic_check_vcpi_alloc_limit(), which doesn't have a state, 
so we still need to have this on the mgr somehow.

I was thinking we could add the slots(or some DP version indicator) 
inside the drm_connector, and add a parameter to 
drm_dp_mst_atomic_check_vcpi_alloc_limit(int slots) and call it with 
this info via drm_dp_mst_atomic_check().


Bhawan

>
>>                  ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-
>>> mst_primary,
>>                                                              mst_state);
>>                  mutex_unlock(&mgr->lock);
>> @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
>> drm_dp_mst_topology_mgr *mgr,
>>          if (!mgr->proposed_vcpis)
>>                  return -ENOMEM;
>>          set_bit(0, &mgr->payload_mask);
>> +       mgr->total_avail_slots = 63;
>> +       mgr->start_slot = 1;
>>   
>>          mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>>          if (mst_state == NULL)
>>                  return -ENOMEM;
>>   
>> +       mst_state->total_avail_slots = 63;
>> +       mst_state->start_slot = 1;
>> +
>>          mst_state->mgr = mgr;
>>          INIT_LIST_HEAD(&mst_state->vcpis);
>>   
>> diff --git a/include/drm/drm_dp_mst_helper.h
>> b/include/drm/drm_dp_mst_helper.h
>> index ddb9231d0309..f8152dfb34ed 100644
>> --- a/include/drm/drm_dp_mst_helper.h
>> +++ b/include/drm/drm_dp_mst_helper.h
>> @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
>>          struct drm_private_state base;
>>          struct list_head vcpis;
>>          struct drm_dp_mst_topology_mgr *mgr;
>> +       u8 total_avail_slots;
>> +       u8 start_slot;
>>   };
>>   
>>   #define to_dp_mst_topology_mgr(x) container_of(x, struct
>> drm_dp_mst_topology_mgr, base)
>> @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
>>           */
>>          int pbn_div;
>>   
>> +       /**
>> +        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
>> +        */
>> +       u8 total_avail_slots;
>> +
>> +       /**
>> +        * @start_slot: 1 for 8b/10b, 0 for 128/132b
>> +        */
>> +       u8 start_slot;
>> +
>>          /**
>>           * @funcs: Atomic helper callbacks
>>           */
>> @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct
>> drm_dp_mst_topology_mgr *mgr, struct drm_dp
>>   
>>   void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
>> struct drm_dp_mst_port *port);
>>   
>> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
>> *mst_state, uint8_t link_coding_cap);
>>   
>>   void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>>                                  struct drm_dp_mst_port *port);

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-14 20:21             ` Bhawanpreet Lakha
@ 2021-10-14 20:22               ` Bhawanpreet Lakha
  2021-10-15 20:04               ` Lyude Paul
  1 sibling, 0 replies; 37+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-14 20:22 UTC (permalink / raw)
  To: Lyude Paul, Jerry.Zuo, dri-devel
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Lipski, Mikita

Adding Mikita aswell

On 2021-10-14 4:21 p.m., Bhawanpreet Lakha wrote:
>
> On 2021-10-13 6:25 p.m., Lyude Paul wrote:
>> Some comments below (also, sorry again for the mixup on the last 
>> review!)
>>
>> On Tue, 2021-10-12 at 17:58 -0400, Bhawanpreet Lakha wrote:
>>> 8b/10b encoding format requires to reserve the first slot for
>>> recording metadata. Real data transmission starts from the second slot,
>>> with a total of available 63 slots available.
>>>
>>> In 128b/132b encoding format, metadata is transmitted separately
>>> in LLCP packet before MTP. Real data transmission starts from
>>> the first slot, with a total of 64 slots available.
>>>
>>> v2:
>>> * Remove get_mst_link_encoding_cap
>>> * Move total/start slots to mst_state, and copy it to mst_mgr in
>>> atomic_check
>>>
>>> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
>>> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
>>> ---
>>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++++++
>>>   drivers/gpu/drm/drm_dp_mst_topology.c         | 35 
>>> +++++++++++++++----
>>>   include/drm/drm_dp_mst_helper.h               | 13 +++++++
>>>   3 files changed, 69 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> index 5020f2d36fe1..4ad50eb0091a 100644
>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> @@ -10612,6 +10612,8 @@ static int amdgpu_dm_atomic_check(struct 
>>> drm_device
>>> *dev,
>>>   #if defined(CONFIG_DRM_AMD_DC_DCN)
>>>          struct dsc_mst_fairness_vars vars[MAX_PIPES];
>>>   #endif
>>> +       struct drm_dp_mst_topology_state *mst_state;
>>> +       struct drm_dp_mst_topology_mgr *mgr;
>>>            trace_amdgpu_dm_atomic_check_begin(state);
>>>   @@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct 
>>> drm_device
>>> *dev,
>>>                  lock_and_validation_needed = true;
>>>          }
>>>   +#if defined(CONFIG_DRM_AMD_DC_DCN)
>>> +       for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
>>> +               struct amdgpu_dm_connector *aconnector;
>>> +               struct drm_connector *connector;
>>> +               struct drm_connector_list_iter iter;
>>> +               u8 link_coding_cap;
>>> +
>>> +               if (!mgr->mst_state )
>>> +                       continue;
>> extraneous space
>>
>>> +
>>> +               drm_connector_list_iter_begin(dev, &iter);
>>> +               drm_for_each_connector_iter(connector, &iter) {
>>> +                       int id = connector->index;
>>> +
>>> +                       if (id == mst_state->mgr->conn_base_id) {
>>> +                               aconnector =
>>> to_amdgpu_dm_connector(connector);
>>> +                               link_coding_cap =
>>> dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
>>> +                               drm_dp_mst_update_coding_cap(mst_state,
>>> link_coding_cap);
>>> +
>>> +                               break;
>>> +                       }
>>> +               }
>>> +               drm_connector_list_iter_end(&iter);
>>> +
>>> +       }
>>> +#endif
>>>          /**
>>>           * Streams and planes are reset when there are changes that 
>>> affect
>>>           * bandwidth. Anything that affects bandwidth needs to go 
>>> through
>>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>>> index ad0795afc21c..fb5c47c4cb2e 100644
>>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>>> @@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct
>>> drm_dp_mst_topology_mgr *mgr)
>>>          struct drm_dp_payload req_payload;
>>>          struct drm_dp_mst_port *port;
>>>          int i, j;
>>> -       int cur_slots = 1;
>>> +       int cur_slots = mgr->start_slot;
>>>          bool skip;
>>>            mutex_lock(&mgr->payload_lock);
>>> @@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct
>>> drm_dp_mst_topology_mgr *mgr,
>>>          num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
>>>            /* max. time slots - one slot for MTP header */
>>> -       if (num_slots > 63)
>>> +       if (num_slots > mgr->total_avail_slots)
>>>                  return -ENOSPC;
>> For reasons I will explain a little further in this email, we might 
>> want to
>> drop this…
>>
>>>          return num_slots;
>>>   }
>>> @@ -4333,7 +4333,7 @@ static int drm_dp_init_vcpi(struct
>>> drm_dp_mst_topology_mgr *mgr,
>>>          int ret;
>>>            /* max. time slots - one slot for MTP header */
>>> -       if (slots > 63)
>>> +       if (slots > mgr->total_avail_slots)
>> …and this
>>
>>>                  return -ENOSPC;
>>>            vcpi->pbn = pbn;
>>> @@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct
>>> drm_atomic_state *state,
>>>   }
>>>   EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>>>   +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
>>> *mst_state, uint8_t link_coding_cap)
>> Need some kdocs here
>>
>>> +{
>>> +       if (link_coding_cap == DP_CAP_ANSI_128B132B) {
>>> +               mst_state->total_avail_slots = 64;
>>> +               mst_state->start_slot = 0;
>>> +       }
>>> +
>>> +       DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
>>> +                       (link_coding_cap == DP_CAP_ANSI_128B132B) ?
>>> "128b/132b":"8b/10b", mst_state->mgr);
>> need to fix indenting here, and wrap this to 100 chars
>>
>>> +}
>>> +EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
>>> +
>>>   /**
>>>    * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>>>    * @mgr: manager for this port
>>> @@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct
>>> drm_dp_mst_topology_mgr *mgr,
>>>            ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
>>>          if (ret) {
>>> -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d 
>>> max=63
>>> ret=%d\n",
>>> -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
>>> +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d 
>>> max=%d
>>> ret=%d\n",
>>> +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
>>>> total_avail_slots, ret);
>>>                  drm_dp_mst_topology_put_port(port);
>>>                  goto out;
>>>          }
>>> @@ -5226,7 +5238,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
>>> drm_dp_mst_topology_mgr *mgr,
>>>                                           struct 
>>> drm_dp_mst_topology_state
>>> *mst_state)
>>>   {
>>>          struct drm_dp_vcpi_allocation *vcpi;
>>> -       int avail_slots = 63, payload_count = 0;
>>> +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
>>>            list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>>>                  /* Releasing VCPI is always OK-even if the port is 
>>> gone */
>>> @@ -5255,7 +5267,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
>>> drm_dp_mst_topology_mgr *mgr,
>>>                  }
>>>          }
>>>          drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI 
>>> avail=%d
>>> used=%d\n",
>>> -                      mgr, mst_state, avail_slots, 63 - avail_slots);
>>> +                      mgr, mst_state, avail_slots, 
>>> mgr->total_avail_slots -
>>> avail_slots);
>>>            return 0;
>>>   }
>>> @@ -5421,6 +5433,10 @@ int drm_dp_mst_atomic_check(struct 
>>> drm_atomic_state
>>> *state)
>>>                          break;
>>>                    mutex_lock(&mgr->lock);
>>> +
>>> +               mgr->start_slot = mst_state->start_slot;
>>> +               mgr->total_avail_slots = mst_state->total_avail_slots;
>>> +
>> this isn't correct - atomic checks aren't allowed to mutate anything 
>> besides
>> the atomic state structure that we're checking since we don't know 
>> whether or
>> not the display state is going to be committed when checking it. If 
>> we're
>> storing state in mgr, that state needs to be written to mgr during 
>> the atomic
>> commit instead of the atomic check.
>>
>> ...but, coming back to this MST code after being gone for a while, I 
>> think it
>> might be time for us to stop worrying about the non-atomic state. 
>> Especially
>> since there's only one driver using it; the legacy radeon.ko; and 
>> right now
>> the plan is either to just drop MST support on radeon.ko or move the 
>> MST code
>> it uses into radeon.ko.Which brings me to say - I think we can drop 
>> some of
>> the hunks I mentioned above (e.g. the changes to drm_dp_init_vcpi and
>> drm_dp_find_vcpi_slots I mentioned above). We can then just update 
>> the kdocs
>> for these functions in a separate patch to clarify that now in 
>> addition to
>> being deprecated, these functions are just broken and will eventually be
>> removed.
>>
>> So - doing that allows us to get rid of mgr->total_avail_slots and mgr-
>>> start_slot entirely, just set the slot info in the atomic state 
>>> during atomic
>> check, and then just rely on the atomic state for
>> drm_dp_atomic_find_vcpi_slots() and friends. Which seems much simpler 
>> to me,
>> does this sound alrght with you?
>
> Thanks for the response,
>
> That function is per port (drm_dp_atomic_find_vcpi_slots) so not sure 
> how that will work, maybe I don't understand what you mean?
>
> Also we only need to check this inside 
> drm_dp_mst_atomic_check_vcpi_alloc_limit(), which doesn't have a 
> state, so we still need to have this on the mgr somehow.
>
> I was thinking we could add the slots(or some DP version indicator) 
> inside the drm_connector, and add a parameter to 
> drm_dp_mst_atomic_check_vcpi_alloc_limit(int slots) and call it with 
> this info via drm_dp_mst_atomic_check().
>
>
> Bhawan
>
>>
>>>                  ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-
>>>> mst_primary,
>>> mst_state);
>>>                  mutex_unlock(&mgr->lock);
>>> @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
>>> drm_dp_mst_topology_mgr *mgr,
>>>          if (!mgr->proposed_vcpis)
>>>                  return -ENOMEM;
>>>          set_bit(0, &mgr->payload_mask);
>>> +       mgr->total_avail_slots = 63;
>>> +       mgr->start_slot = 1;
>>>            mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>>>          if (mst_state == NULL)
>>>                  return -ENOMEM;
>>>   +       mst_state->total_avail_slots = 63;
>>> +       mst_state->start_slot = 1;
>>> +
>>>          mst_state->mgr = mgr;
>>>          INIT_LIST_HEAD(&mst_state->vcpis);
>>>   diff --git a/include/drm/drm_dp_mst_helper.h
>>> b/include/drm/drm_dp_mst_helper.h
>>> index ddb9231d0309..f8152dfb34ed 100644
>>> --- a/include/drm/drm_dp_mst_helper.h
>>> +++ b/include/drm/drm_dp_mst_helper.h
>>> @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
>>>          struct drm_private_state base;
>>>          struct list_head vcpis;
>>>          struct drm_dp_mst_topology_mgr *mgr;
>>> +       u8 total_avail_slots;
>>> +       u8 start_slot;
>>>   };
>>>     #define to_dp_mst_topology_mgr(x) container_of(x, struct
>>> drm_dp_mst_topology_mgr, base)
>>> @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
>>>           */
>>>          int pbn_div;
>>>   +       /**
>>> +        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
>>> +        */
>>> +       u8 total_avail_slots;
>>> +
>>> +       /**
>>> +        * @start_slot: 1 for 8b/10b, 0 for 128/132b
>>> +        */
>>> +       u8 start_slot;
>>> +
>>>          /**
>>>           * @funcs: Atomic helper callbacks
>>>           */
>>> @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct
>>> drm_dp_mst_topology_mgr *mgr, struct drm_dp
>>>     void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr 
>>> *mgr,
>>> struct drm_dp_mst_port *port);
>>>   +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
>>> *mst_state, uint8_t link_coding_cap);
>>>     void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr 
>>> *mgr,
>>>                                  struct drm_dp_mst_port *port);

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-13 22:25           ` Lyude Paul
  2021-10-14 20:21             ` Bhawanpreet Lakha
@ 2021-10-15 19:43             ` Bhawanpreet Lakha
  2021-10-15 20:41               ` Lyude Paul
  1 sibling, 1 reply; 37+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-15 19:43 UTC (permalink / raw)
  To: Lyude Paul, Jerry.Zuo, dri-devel
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Lipski, Mikita


On 2021-10-13 6:25 p.m., Lyude Paul wrote:
> Some comments below (also, sorry again for the mixup on the last review!)
>
> On Tue, 2021-10-12 at 17:58 -0400, Bhawanpreet Lakha wrote:
>> 8b/10b encoding format requires to reserve the first slot for
>> recording metadata. Real data transmission starts from the second slot,
>> with a total of available 63 slots available.
>>
>> In 128b/132b encoding format, metadata is transmitted separately
>> in LLCP packet before MTP. Real data transmission starts from
>> the first slot, with a total of 64 slots available.
>>
>> v2:
>> * Remove get_mst_link_encoding_cap
>> * Move total/start slots to mst_state, and copy it to mst_mgr in
>> atomic_check
>>
>> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
>> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
>> ---
>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++++++
>>   drivers/gpu/drm/drm_dp_mst_topology.c         | 35 +++++++++++++++----
>>   include/drm/drm_dp_mst_helper.h               | 13 +++++++
>>   3 files changed, 69 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> index 5020f2d36fe1..4ad50eb0091a 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -10612,6 +10612,8 @@ static int amdgpu_dm_atomic_check(struct drm_device
>> *dev,
>>   #if defined(CONFIG_DRM_AMD_DC_DCN)
>>          struct dsc_mst_fairness_vars vars[MAX_PIPES];
>>   #endif
>> +       struct drm_dp_mst_topology_state *mst_state;
>> +       struct drm_dp_mst_topology_mgr *mgr;
>>   
>>          trace_amdgpu_dm_atomic_check_begin(state);
>>   
>> @@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device
>> *dev,
>>                  lock_and_validation_needed = true;
>>          }
>>   
>> +#if defined(CONFIG_DRM_AMD_DC_DCN)
>> +       for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
>> +               struct amdgpu_dm_connector *aconnector;
>> +               struct drm_connector *connector;
>> +               struct drm_connector_list_iter iter;
>> +               u8 link_coding_cap;
>> +
>> +               if (!mgr->mst_state )
>> +                       continue;
> extraneous space
>
>> +
>> +               drm_connector_list_iter_begin(dev, &iter);
>> +               drm_for_each_connector_iter(connector, &iter) {
>> +                       int id = connector->index;
>> +
>> +                       if (id == mst_state->mgr->conn_base_id) {
>> +                               aconnector =
>> to_amdgpu_dm_connector(connector);
>> +                               link_coding_cap =
>> dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
>> +                               drm_dp_mst_update_coding_cap(mst_state,
>> link_coding_cap);
>> +
>> +                               break;
>> +                       }
>> +               }
>> +               drm_connector_list_iter_end(&iter);
>> +
>> +       }
>> +#endif
>>          /**
>>           * Streams and planes are reset when there are changes that affect
>>           * bandwidth. Anything that affects bandwidth needs to go through
>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>> index ad0795afc21c..fb5c47c4cb2e 100644
>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>> @@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct
>> drm_dp_mst_topology_mgr *mgr)
>>          struct drm_dp_payload req_payload;
>>          struct drm_dp_mst_port *port;
>>          int i, j;
>> -       int cur_slots = 1;
>> +       int cur_slots = mgr->start_slot;
>>          bool skip;
>>   
>>          mutex_lock(&mgr->payload_lock);
>> @@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct
>> drm_dp_mst_topology_mgr *mgr,
>>          num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
>>   
>>          /* max. time slots - one slot for MTP header */
>> -       if (num_slots > 63)
>> +       if (num_slots > mgr->total_avail_slots)
>>                  return -ENOSPC;
> For reasons I will explain a little further in this email, we might want to
> drop this…
>
>>          return num_slots;
>>   }
>> @@ -4333,7 +4333,7 @@ static int drm_dp_init_vcpi(struct
>> drm_dp_mst_topology_mgr *mgr,
>>          int ret;
>>   
>>          /* max. time slots - one slot for MTP header */
>> -       if (slots > 63)
>> +       if (slots > mgr->total_avail_slots)
> …and this
>
>>                  return -ENOSPC;
>>   
>>          vcpi->pbn = pbn;
>> @@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct
>> drm_atomic_state *state,
>>   }
>>   EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>>   
>> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
>> *mst_state, uint8_t link_coding_cap)
> Need some kdocs here
>
>> +{
>> +       if (link_coding_cap == DP_CAP_ANSI_128B132B) {
>> +               mst_state->total_avail_slots = 64;
>> +               mst_state->start_slot = 0;
>> +       }
>> +
>> +       DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
>> +                       (link_coding_cap == DP_CAP_ANSI_128B132B) ?
>> "128b/132b":"8b/10b", mst_state->mgr);
> need to fix indenting here, and wrap this to 100 chars
>
>> +}
>> +EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
>> +
>>   /**
>>    * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>>    * @mgr: manager for this port
>> @@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct
>> drm_dp_mst_topology_mgr *mgr,
>>   
>>          ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
>>          if (ret) {
>> -               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63
>> ret=%d\n",
>> -                           DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
>> +               drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=%d
>> ret=%d\n",
>> +                           DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
>>> total_avail_slots, ret);
>>                  drm_dp_mst_topology_put_port(port);
>>                  goto out;
>>          }
>> @@ -5226,7 +5238,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
>> drm_dp_mst_topology_mgr *mgr,
>>                                           struct drm_dp_mst_topology_state
>> *mst_state)
>>   {
>>          struct drm_dp_vcpi_allocation *vcpi;
>> -       int avail_slots = 63, payload_count = 0;
>> +       int avail_slots = mgr->total_avail_slots, payload_count = 0;
>>   
>>          list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>>                  /* Releasing VCPI is always OK-even if the port is gone */
>> @@ -5255,7 +5267,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
>> drm_dp_mst_topology_mgr *mgr,
>>                  }
>>          }
>>          drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d
>> used=%d\n",
>> -                      mgr, mst_state, avail_slots, 63 - avail_slots);
>> +                      mgr, mst_state, avail_slots, mgr->total_avail_slots -
>> avail_slots);
>>   
>>          return 0;
>>   }
>> @@ -5421,6 +5433,10 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state
>> *state)
>>                          break;
>>   
>>                  mutex_lock(&mgr->lock);
>> +
>> +               mgr->start_slot = mst_state->start_slot;
>> +               mgr->total_avail_slots = mst_state->total_avail_slots;
>> +
> this isn't correct - atomic checks aren't allowed to mutate anything besides
> the atomic state structure that we're checking since we don't know whether or
> not the display state is going to be committed when checking it. If we're
> storing state in mgr, that state needs to be written to mgr during the atomic
> commit instead of the atomic check.
>
> ...but, coming back to this MST code after being gone for a while, I think it
> might be time for us to stop worrying about the non-atomic state. Especially
> since there's only one driver using it; the legacy radeon.ko; and right now
> the plan is either to just drop MST support on radeon.ko or move the MST code
> it uses into radeon.ko.Which brings me to say - I think we can drop some of
> the hunks I mentioned above (e.g. the changes to drm_dp_init_vcpi and
> drm_dp_find_vcpi_slots I mentioned above). We can then just update the kdocs
> for these functions in a separate patch to clarify that now in addition to
> being deprecated, these functions are just broken and will eventually be
> removed.
>
> So - doing that allows us to get rid of mgr->total_avail_slots and mgr-
>> start_slot entirely, just set the slot info in the atomic state during atomic
> check, and then just rely on the atomic state for
> drm_dp_atomic_find_vcpi_slots() and friends. Which seems much simpler to me,
> does this sound alrght with you?
>
Thanks for the response,

That function is per port so not sure how that will work. Also we only 
need to check this inside drm_dp_mst_atomic_check_vcpi_alloc_limit(), 
which doesn't have a state.

We could add the slots(or some DP version indicator) inside the 
drm_connector, and add a parameter to 
drm_dp_mst_atomic_check_vcpi_alloc_limit(int slots)? and call it with 
this info via drm_dp_mst_atomic_check() and then update the mgr->slot in 
commit.


Bhawan

>>                  ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-
>>> mst_primary,
>>                                                              mst_state);
>>                  mutex_unlock(&mgr->lock);
>> @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
>> drm_dp_mst_topology_mgr *mgr,
>>          if (!mgr->proposed_vcpis)
>>                  return -ENOMEM;
>>          set_bit(0, &mgr->payload_mask);
>> +       mgr->total_avail_slots = 63;
>> +       mgr->start_slot = 1;
>>   
>>          mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>>          if (mst_state == NULL)
>>                  return -ENOMEM;
>>   
>> +       mst_state->total_avail_slots = 63;
>> +       mst_state->start_slot = 1;
>> +
>>          mst_state->mgr = mgr;
>>          INIT_LIST_HEAD(&mst_state->vcpis);
>>   
>> diff --git a/include/drm/drm_dp_mst_helper.h
>> b/include/drm/drm_dp_mst_helper.h
>> index ddb9231d0309..f8152dfb34ed 100644
>> --- a/include/drm/drm_dp_mst_helper.h
>> +++ b/include/drm/drm_dp_mst_helper.h
>> @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
>>          struct drm_private_state base;
>>          struct list_head vcpis;
>>          struct drm_dp_mst_topology_mgr *mgr;
>> +       u8 total_avail_slots;
>> +       u8 start_slot;
>>   };
>>   
>>   #define to_dp_mst_topology_mgr(x) container_of(x, struct
>> drm_dp_mst_topology_mgr, base)
>> @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
>>           */
>>          int pbn_div;
>>   
>> +       /**
>> +        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
>> +        */
>> +       u8 total_avail_slots;
>> +
>> +       /**
>> +        * @start_slot: 1 for 8b/10b, 0 for 128/132b
>> +        */
>> +       u8 start_slot;
>> +
>>          /**
>>           * @funcs: Atomic helper callbacks
>>           */
>> @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct
>> drm_dp_mst_topology_mgr *mgr, struct drm_dp
>>   
>>   void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
>> struct drm_dp_mst_port *port);
>>   
>> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
>> *mst_state, uint8_t link_coding_cap);
>>   
>>   void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>>                                  struct drm_dp_mst_port *port);

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-14 20:21             ` Bhawanpreet Lakha
  2021-10-14 20:22               ` Bhawanpreet Lakha
@ 2021-10-15 20:04               ` Lyude Paul
  1 sibling, 0 replies; 37+ messages in thread
From: Lyude Paul @ 2021-10-15 20:04 UTC (permalink / raw)
  To: Bhawanpreet Lakha, Jerry.Zuo, dri-devel
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas

[snip]

On Thu, 2021-10-14 at 16:21 -0400, Bhawanpreet Lakha wrote:
> 
> Thanks for the response,
> 
> That function is per port (drm_dp_atomic_find_vcpi_slots) so not sure 
> how that will work, maybe I don't understand what you mean?

Yeah - drm_dp_atomic_find_vcpi_slots() is just one part of the atomic helpers
though, we can always add more. JFYI, the main atomic check function for MST
is drm_dp_mst_atomic_check(). So we'd probably just want to add something into
drm_dp_mst_topology_state that handles making sure we go through
drm_dp_vcpi_allocation struct and recalculates everything in it. We might also
want to add an atomic helper to set the new starting slot and slot count in
the atomic state, then go through the current atomic topology state and ensure
that we add any CRTCs that would need full modesets as a result of that info
changing.

> 
> Also we only need to check this inside 
> drm_dp_mst_atomic_check_vcpi_alloc_limit(), which doesn't have a state, 
> so we still need to have this on the mgr somehow.

It does, we pass drm_dp_mst_topology_state to it. So we could just add these
fields there.

> 
> I was thinking we could add the slots(or some DP version indicator) 
> inside the drm_connector, and add a parameter to 
> drm_dp_mst_atomic_check_vcpi_alloc_limit(int slots) and call it with 
> this info via drm_dp_mst_atomic_check().

So before I continue: I should note that some of the code in MST goes against
what I'm about to say, in particular a lot of the payload updating functions
in MST that keep their payload state outside of drm_dp_mst_topology_state and
friends, but that's because some of this code is old and needs to be updated
anyway (and some of it was actually just being kept around because we were
worried about breaking radeon.ko, the only driver relying on behavior from the
non-atomic paths in our topology helper). Also - I'm not sure what your prior
experience is with modesetting in the linux kernel so my apologies if I'm
explaining anything you already understand here.

Anyway-drm_connector wouldn't be the right place to put it because it's not
part of the atomic state. The reason we have atomic modesetting in the first
place is so that we can come up with a new display state, and then have the
kernel verify the configurations in that new state and potentially reject it
if we tried to program something that wouldn't have worked in hardware. As
well, having it in drm_connector would mean that it wouldn't be safe to access
unless we've somehow locked the drm_connector. drm_connector_state would be
'safe' to have this data in, but considering that we already have a private
atomic state object for MST (drm_dp_mst_topology_state) it doesn't make much
sense to keep MST info elsewhere.

> 
> 
> Bhawan
> 
> > 
> > >                  ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-
> > > > mst_primary,
> > >                                                              mst_state);
> > >                  mutex_unlock(&mgr->lock);
> > > @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >          if (!mgr->proposed_vcpis)
> > >                  return -ENOMEM;
> > >          set_bit(0, &mgr->payload_mask);
> > > +       mgr->total_avail_slots = 63;
> > > +       mgr->start_slot = 1;
> > >   
> > >          mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
> > >          if (mst_state == NULL)
> > >                  return -ENOMEM;
> > >   
> > > +       mst_state->total_avail_slots = 63;
> > > +       mst_state->start_slot = 1;
> > > +
> > >          mst_state->mgr = mgr;
> > >          INIT_LIST_HEAD(&mst_state->vcpis);
> > >   
> > > diff --git a/include/drm/drm_dp_mst_helper.h
> > > b/include/drm/drm_dp_mst_helper.h
> > > index ddb9231d0309..f8152dfb34ed 100644
> > > --- a/include/drm/drm_dp_mst_helper.h
> > > +++ b/include/drm/drm_dp_mst_helper.h
> > > @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
> > >          struct drm_private_state base;
> > >          struct list_head vcpis;
> > >          struct drm_dp_mst_topology_mgr *mgr;
> > > +       u8 total_avail_slots;
> > > +       u8 start_slot;
> > >   };
> > >   
> > >   #define to_dp_mst_topology_mgr(x) container_of(x, struct
> > > drm_dp_mst_topology_mgr, base)
> > > @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
> > >           */
> > >          int pbn_div;
> > >   
> > > +       /**
> > > +        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
> > > +        */
> > > +       u8 total_avail_slots;
> > > +
> > > +       /**
> > > +        * @start_slot: 1 for 8b/10b, 0 for 128/132b
> > > +        */
> > > +       u8 start_slot;
> > > +
> > >          /**
> > >           * @funcs: Atomic helper callbacks
> > >           */
> > > @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct
> > > drm_dp_mst_topology_mgr *mgr, struct drm_dp
> > >   
> > >   void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
> > > struct drm_dp_mst_port *port);
> > >   
> > > +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
> > > *mst_state, uint8_t link_coding_cap);
> > >   
> > >   void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
> > >                                  struct drm_dp_mst_port *port);
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-15 19:43             ` Bhawanpreet Lakha
@ 2021-10-15 20:41               ` Lyude Paul
  2021-10-18 19:47                 ` Bhawanpreet Lakha
  0 siblings, 1 reply; 37+ messages in thread
From: Lyude Paul @ 2021-10-15 20:41 UTC (permalink / raw)
  To: Bhawanpreet Lakha, Jerry.Zuo, dri-devel
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Lipski, Mikita

[more snip]

On Fri, 2021-10-15 at 15:43 -0400, Bhawanpreet Lakha wrote:
> > 
> Thanks for the response,
> 
> That function is per port so not sure how that will work. Also we only 
> need to check this inside drm_dp_mst_atomic_check_vcpi_alloc_limit(), 
> which doesn't have a state.
> 
> We could add the slots(or some DP version indicator) inside the 
> drm_connector, and add a parameter to 
> drm_dp_mst_atomic_check_vcpi_alloc_limit(int slots)? and call it with 
> this info via drm_dp_mst_atomic_check() and then update the mgr->slot in 
> commit.

TBH - I think we can actually just get away with having all of this info in
drm_dp_mst_topology_state

> 
> 
> Bhawan
> 
> > >                  ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-
> > > > mst_primary,
> > >                                                              mst_state);
> > >                  mutex_unlock(&mgr->lock);
> > > @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
> > > drm_dp_mst_topology_mgr *mgr,
> > >          if (!mgr->proposed_vcpis)
> > >                  return -ENOMEM;
> > >          set_bit(0, &mgr->payload_mask);
> > > +       mgr->total_avail_slots = 63;
> > > +       mgr->start_slot = 1;
> > >   
> > >          mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
> > >          if (mst_state == NULL)
> > >                  return -ENOMEM;
> > >   
> > > +       mst_state->total_avail_slots = 63;
> > > +       mst_state->start_slot = 1;
> > > +
> > >          mst_state->mgr = mgr;
> > >          INIT_LIST_HEAD(&mst_state->vcpis);
> > >   
> > > diff --git a/include/drm/drm_dp_mst_helper.h
> > > b/include/drm/drm_dp_mst_helper.h
> > > index ddb9231d0309..f8152dfb34ed 100644
> > > --- a/include/drm/drm_dp_mst_helper.h
> > > +++ b/include/drm/drm_dp_mst_helper.h
> > > @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
> > >          struct drm_private_state base;
> > >          struct list_head vcpis;
> > >          struct drm_dp_mst_topology_mgr *mgr;
> > > +       u8 total_avail_slots;
> > > +       u8 start_slot;
> > >   };
> > >   
> > >   #define to_dp_mst_topology_mgr(x) container_of(x, struct
> > > drm_dp_mst_topology_mgr, base)
> > > @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
> > >           */
> > >          int pbn_div;
> > >   
> > > +       /**
> > > +        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
> > > +        */
> > > +       u8 total_avail_slots;
> > > +
> > > +       /**
> > > +        * @start_slot: 1 for 8b/10b, 0 for 128/132b
> > > +        */
> > > +       u8 start_slot;
> > > +
> > >          /**
> > >           * @funcs: Atomic helper callbacks
> > >           */
> > > @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct
> > > drm_dp_mst_topology_mgr *mgr, struct drm_dp
> > >   
> > >   void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
> > > struct drm_dp_mst_port *port);
> > >   
> > > +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
> > > *mst_state, uint8_t link_coding_cap);
> > >   
> > >   void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
> > >                                  struct drm_dp_mst_port *port);
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-15 20:41               ` Lyude Paul
@ 2021-10-18 19:47                 ` Bhawanpreet Lakha
  2021-10-18 23:17                   ` Lyude Paul
  0 siblings, 1 reply; 37+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-18 19:47 UTC (permalink / raw)
  To: Lyude Paul, Jerry.Zuo, dri-devel
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Lipski, Mikita

I understand the mst_state argument its just that most of the mst 
functions are using mst_mgr/port structs and there is no easy way to 
extract the mst_state using mgr/port in these places 
(drm_dp_update_payload_part1, drm_dp_mst_allocate_vcpi, drm_dp_init_vcpi 
etc) where we need the slot info.

So either we need to keep a copy of the slots in the mgr because that's 
what most of the code is using right now or pass around the atomic state 
to get the mgr->state mapping. (I don't have much experience with the 
mst code so maybe I am missing some key detail here?)


Thanks,

Bhawan


On 2021-10-15 4:41 p.m., Lyude Paul wrote:
> [more snip]
>
> On Fri, 2021-10-15 at 15:43 -0400, Bhawanpreet Lakha wrote:
>> Thanks for the response,
>>
>> That function is per port so not sure how that will work. Also we only
>> need to check this inside drm_dp_mst_atomic_check_vcpi_alloc_limit(),
>> which doesn't have a state.
>>
>> We could add the slots(or some DP version indicator) inside the
>> drm_connector, and add a parameter to
>> drm_dp_mst_atomic_check_vcpi_alloc_limit(int slots)? and call it with
>> this info via drm_dp_mst_atomic_check() and then update the mgr->slot in
>> commit.
> TBH - I think we can actually just get away with having all of this info in
> drm_dp_mst_topology_state
>
>>
>> Bhawan
>>
>>>>                   ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-
>>>>> mst_primary,
>>>>                                                               mst_state);
>>>>                   mutex_unlock(&mgr->lock);
>>>> @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
>>>> drm_dp_mst_topology_mgr *mgr,
>>>>           if (!mgr->proposed_vcpis)
>>>>                   return -ENOMEM;
>>>>           set_bit(0, &mgr->payload_mask);
>>>> +       mgr->total_avail_slots = 63;
>>>> +       mgr->start_slot = 1;
>>>>    
>>>>           mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>>>>           if (mst_state == NULL)
>>>>                   return -ENOMEM;
>>>>    
>>>> +       mst_state->total_avail_slots = 63;
>>>> +       mst_state->start_slot = 1;
>>>> +
>>>>           mst_state->mgr = mgr;
>>>>           INIT_LIST_HEAD(&mst_state->vcpis);
>>>>    
>>>> diff --git a/include/drm/drm_dp_mst_helper.h
>>>> b/include/drm/drm_dp_mst_helper.h
>>>> index ddb9231d0309..f8152dfb34ed 100644
>>>> --- a/include/drm/drm_dp_mst_helper.h
>>>> +++ b/include/drm/drm_dp_mst_helper.h
>>>> @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
>>>>           struct drm_private_state base;
>>>>           struct list_head vcpis;
>>>>           struct drm_dp_mst_topology_mgr *mgr;
>>>> +       u8 total_avail_slots;
>>>> +       u8 start_slot;
>>>>    };
>>>>    
>>>>    #define to_dp_mst_topology_mgr(x) container_of(x, struct
>>>> drm_dp_mst_topology_mgr, base)
>>>> @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
>>>>            */
>>>>           int pbn_div;
>>>>    
>>>> +       /**
>>>> +        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
>>>> +        */
>>>> +       u8 total_avail_slots;
>>>> +
>>>> +       /**
>>>> +        * @start_slot: 1 for 8b/10b, 0 for 128/132b
>>>> +        */
>>>> +       u8 start_slot;
>>>> +
>>>>           /**
>>>>            * @funcs: Atomic helper callbacks
>>>>            */
>>>> @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct
>>>> drm_dp_mst_topology_mgr *mgr, struct drm_dp
>>>>    
>>>>    void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
>>>> struct drm_dp_mst_port *port);
>>>>    
>>>> +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
>>>> *mst_state, uint8_t link_coding_cap);
>>>>    
>>>>    void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>>>>                                   struct drm_dp_mst_port *port);

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-18 19:47                 ` Bhawanpreet Lakha
@ 2021-10-18 23:17                   ` Lyude Paul
  2021-10-19 18:01                     ` [PATCH 2/4] " Bhawanpreet Lakha
  0 siblings, 1 reply; 37+ messages in thread
From: Lyude Paul @ 2021-10-18 23:17 UTC (permalink / raw)
  To: Bhawanpreet Lakha, Jerry.Zuo, dri-devel
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Lipski, Mikita

First off, sidenote: I wonder if we even need total_avail_slots and
could just use start_slot. Anyway, more productive comments below:

On Mon, 2021-10-18 at 15:47 -0400, Bhawanpreet Lakha wrote:
> I understand the mst_state argument its just that most of the mst
> functions are using mst_mgr/port structs and there is no easy way to
> extract the mst_state using mgr/port in these places
> (drm_dp_update_payload_part1, drm_dp_mst_allocate_vcpi, drm_dp_init_vcpi
> etc) where we need the slot info.
>
Ahh, I see why this might be confusing. I think surprisingly though,
this actually should probably be OK. Mostly, two of these functions
don't actually need the slot count and one I think I have a workaround
for:

* drm_dp_init_vcpi() - This function does use the total slot count here:

    if (slots > 63)
            return -ENOSPC;

  However, drm_dp_init_vcpi() assigns the current payload which means
  it's called by the driver at commit time, not atomic check time. Since
  atomic commits are only allowed to happen after we've successfully
  tested the state in question, we aren't allowed to fail them in the
  middle of a commit - which is definitely what we're doing in
  drm_dp_init_vcpi(). So, I'd actually say we should either totally
  ignore this bit of drm_dp_init_vcpi() or preferably, just entirely
  drop it in a prerequisite patch.
  (If you aren't familiar with atomic modesetting, the reason we "can't"
  just fail in the middle of committing a new atomic state is because we
  may very well have already committed that state to hardware partially.
  So, there's no nice way of aborting at that point without seriously
  complicating things - hence the need for having an atomic check before
  commits)

* drm_dp_mst_allocate_vcpi() - this seems to only be an issue because of
  drm_dp_init_vcpi(), and we additionally print the maximum number of
  slots in a drm_dbg_kms() message:

    drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63 ret=%d\n",
                …

  Since we should have already decided
  all of the new payloads by the time we're in drm_dp_mst_allocate_vcpi
  (again, since we're in atomic commit), that's probably not the best
  place for us to print that anyway. So, I think we'd be fine just
  dropping the "max=63" from that string.

* drm_dp_update_payload_part1() - This one does need the current slot
  count, you're right. I would normally say we should just fix this
  function and move the payload info over to the atomic state, which is
  the eventual plan, but doing that would require dealing with the
  radeon.ko MST mess which is probably too much to ask for with
  something as simple as this patch. I think I know a workaround though:
  Let's keep this new slot info (e.g. num_slots, and possibly
  total_avail_slots if we keep that) in the MST atomic state, _but_ as a
  temporary solution we can instead add a start_slot argument to
  drm_dp_update_payload_part1(). That way we have an easy solution for
  making sure radeon still compiles, and atomic drivers can just extract
  the start_slot info themselves from the topology state and pass it
  into drm_dp_update_payload_part1(). Then I can get rid of that
  start_slots argument at a later date when I've started moving all of
  the payload info for MST into the atomic state.
  If we do this solution though, we should definitely document in the
  patch and in the kdocs for drm_dp_update_payload_part1() that passing
  the start slot is a temporary workaround for non-atomic drivers, and
  will be removed when non-atomic portions of the MST helpers have been
  moved out of helpers and into atomic state.

Does this sound good? There's a lot of moving pieces here so hopefully I
didn't miss anything

> So either we need to keep a copy of the slots in the mgr because that's
> what most of the code is using right now or pass around the atomic state
> to get the mgr->state mapping. (I don't have much experience with the
> mst code so maybe I am missing some key detail here?)

Worst case scenario, if there was something I missed that implies we DO
need access to a mgr->state mapping, I might be OK with us using that in
the interim for these patches. I don't think we need that quite yet as
far as I can tell though.

>
>
> Thanks,
>
> Bhawan
>
>
> On 2021-10-15 4:41 p.m., Lyude Paul wrote:
> > [more snip]
> >
> > On Fri, 2021-10-15 at 15:43 -0400, Bhawanpreet Lakha wrote:
> > > Thanks for the response,
> > >
> > > That function is per port so not sure how that will work. Also we only
> > > need to check this inside drm_dp_mst_atomic_check_vcpi_alloc_limit(),
> > > which doesn't have a state.
> > >
> > > We could add the slots(or some DP version indicator) inside the
> > > drm_connector, and add a parameter to
> > > drm_dp_mst_atomic_check_vcpi_alloc_limit(int slots)? and call it with
> > > this info via drm_dp_mst_atomic_check() and then update the mgr->slot in
> > > commit.
> > TBH - I think we can actually just get away with having all of this info
> > in
> > drm_dp_mst_topology_state
> >
> > >
> > > Bhawan
> > >
> > > > >                   ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-
> > > > > > mst_primary,
> > > > >                                                              
> > > > > mst_state);
> > > > >                   mutex_unlock(&mgr->lock);
> > > > > @@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
> > > > > drm_dp_mst_topology_mgr *mgr,
> > > > >           if (!mgr->proposed_vcpis)
> > > > >                   return -ENOMEM;
> > > > >           set_bit(0, &mgr->payload_mask);
> > > > > +       mgr->total_avail_slots = 63;
> > > > > +       mgr->start_slot = 1;
> > > > >   
> > > > >           mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
> > > > >           if (mst_state == NULL)
> > > > >                   return -ENOMEM;
> > > > >   
> > > > > +       mst_state->total_avail_slots = 63;
> > > > > +       mst_state->start_slot = 1;
> > > > > +
> > > > >           mst_state->mgr = mgr;
> > > > >           INIT_LIST_HEAD(&mst_state->vcpis);
> > > > >   
> > > > > diff --git a/include/drm/drm_dp_mst_helper.h
> > > > > b/include/drm/drm_dp_mst_helper.h
> > > > > index ddb9231d0309..f8152dfb34ed 100644
> > > > > --- a/include/drm/drm_dp_mst_helper.h
> > > > > +++ b/include/drm/drm_dp_mst_helper.h
> > > > > @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
> > > > >           struct drm_private_state base;
> > > > >           struct list_head vcpis;
> > > > >           struct drm_dp_mst_topology_mgr *mgr;
> > > > > +       u8 total_avail_slots;
> > > > > +       u8 start_slot;
> > > > >    };
> > > > >   
> > > > >    #define to_dp_mst_topology_mgr(x) container_of(x, struct
> > > > > drm_dp_mst_topology_mgr, base)
> > > > > @@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
> > > > >            */
> > > > >           int pbn_div;
> > > > >   
> > > > > +       /**
> > > > > +        * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
> > > > > +        */
> > > > > +       u8 total_avail_slots;
> > > > > +
> > > > > +       /**
> > > > > +        * @start_slot: 1 for 8b/10b, 0 for 128/132b
> > > > > +        */
> > > > > +       u8 start_slot;
> > > > > +
> > > > >           /**
> > > > >            * @funcs: Atomic helper callbacks
> > > > >            */
> > > > > @@ -806,6 +818,7 @@ int drm_dp_mst_get_vcpi_slots(struct
> > > > > drm_dp_mst_topology_mgr *mgr, struct drm_dp
> > > > >   
> > > > >    void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr
> > > > > *mgr,
> > > > > struct drm_dp_mst_port *port);
> > > > >   
> > > > > +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
> > > > > *mst_state, uint8_t link_coding_cap);
> > > > >   
> > > > >    void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr
> > > > > *mgr,
> > > > >                                   struct drm_dp_mst_port *port);
>

--
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-18 23:17                   ` Lyude Paul
@ 2021-10-19 18:01                     ` Bhawanpreet Lakha
  2021-10-20  8:34                       ` Jani Nikula
  0 siblings, 1 reply; 37+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-19 18:01 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski,
	Bhawanpreet Lakha

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

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

v2:
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

v3:
* Only keep the slot info on the mst_state
* add a start_slot parameter to the payload function, to facilitate non
  atomic drivers (this is a temporary workaround and should be removed when
  we are moving out the non atomic driver helpers)

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  2 +-
 drivers/gpu/drm/drm_dp_mst_topology.c         | 34 ++++++++++++++++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  4 +--
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  2 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  4 +--
 include/drm/drm_dp_mst_helper.h               |  5 ++-
 6 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index ff0f91c93ba4..6169488e2011 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -251,7 +251,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 	}
 
 	/* It's OK for this to fail */
-	drm_dp_update_payload_part1(mst_mgr);
+	drm_dp_update_payload_part1(mst_mgr, 1);
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
 	 * AUX message. The sequence is slot 1-63 allocated sequence for each
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 5ab3b3a46e89..d188a5269070 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3353,6 +3353,9 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
 /**
  * drm_dp_update_payload_part1() - Execute payload update part 1
  * @mgr: manager to use.
+ * @start_slot: this is the cur slot
+ *  NOTE: start_slot is a temporary workaround for non-atomic drivers,
+ *  this will be removed when non-atomic mst helpers are moved out of the helper
  *
  * This iterates over all proposed virtual channels, and tries to
  * allocate space in the link for them. For 0->slots transitions,
@@ -3363,12 +3366,12 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
  * after calling this the driver should generate ACT and payload
  * packets.
  */
-int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot)
 {
 	struct drm_dp_payload req_payload;
 	struct drm_dp_mst_port *port;
 	int i, j;
-	int cur_slots = 1;
+	int cur_slots = start_slot;
 	bool skip;
 
 	mutex_lock(&mgr->payload_lock);
@@ -4503,6 +4506,26 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 
+/**
+ * drm_dp_mst_update_slots() - updates the slot info depending on the DP ecoding format
+ * @mst_state: mst_state to update
+ * @link_ecoding_cap: the ecoding format on the link
+ */
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_ecoding_cap)
+{
+	if (link_ecoding_cap == DP_CAP_ANSI_128B132B) {
+		mst_state->total_avail_slots = 64;
+		mst_state->start_slot = 0;
+	} else {
+		mst_state->total_avail_slots = 63;
+		mst_state->start_slot = 1;
+	}
+
+	DRM_DEBUG_KMS("%s ecoding format on mst_state 0x%p\n",
+			(link_ecoding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b", mst_state->mgr);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_slots);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -5222,7 +5245,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 					 struct drm_dp_mst_topology_state *mst_state)
 {
 	struct drm_dp_vcpi_allocation *vcpi;
-	int avail_slots = 63, payload_count = 0;
+	int avail_slots = mst_state->total_avail_slots, payload_count = 0;
 
 	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
 		/* Releasing VCPI is always OK-even if the port is gone */
@@ -5251,7 +5274,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 		}
 	}
 	drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
-		       mgr, mst_state, avail_slots, 63 - avail_slots);
+		       mgr, mst_state, avail_slots, mst_state->total_avail_slots - avail_slots);
 
 	return 0;
 }
@@ -5528,6 +5551,9 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	if (mst_state == NULL)
 		return -ENOMEM;
 
+	mst_state->total_avail_slots = 63;
+	mst_state->start_slot = 1;
+
 	mst_state->mgr = mgr;
 	INIT_LIST_HEAD(&mst_state->vcpis);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b170e272bdee..d3a24189a12c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -368,7 +368,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 
 	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
 
-	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
 	if (ret) {
 		drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
 	}
@@ -516,7 +516,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
 
 	intel_dp->active_mst_links++;
 
-	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
 
 	/*
 	 * Before Gen 12 this is not done as part of
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index f949767698fc..6c8c59c26dbf 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1413,7 +1413,7 @@ nv50_mstm_prepare(struct nv50_mstm *mstm)
 	int ret;
 
 	NV_ATOMIC(drm, "%s: mstm prepare\n", mstm->outp->base.base.name);
-	ret = drm_dp_update_payload_part1(&mstm->mgr);
+	ret = drm_dp_update_payload_part1(&mstm->mgr, 1);
 
 	drm_for_each_encoder(encoder, mstm->outp->base.base.dev) {
 		if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) {
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index ec867fa880a4..751c2c075e09 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -423,7 +423,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
 		drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
 					 radeon_connector->port,
 					 mst_enc->pbn, slots);
-		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
+		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
 
 		radeon_dp_mst_set_be_cntl(primary, mst_enc,
 					  radeon_connector->mst_port->hpd.hpd, true);
@@ -452,7 +452,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
 			return;
 
 		drm_dp_mst_reset_vcpi_slots(&radeon_connector->mst_port->mst_mgr, mst_enc->port);
-		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
+		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
 
 		drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);
 		/* and this can also fail */
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index ddb9231d0309..3207b49586fc 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
 	struct drm_private_state base;
 	struct list_head vcpis;
 	struct drm_dp_mst_topology_mgr *mgr;
+	u8 total_avail_slots;
+	u8 start_slot;
 };
 
 #define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
@@ -806,6 +808,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
 
 void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_ecoding_cap);
 
 void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 				struct drm_dp_mst_port *port);
@@ -815,7 +818,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
 			   int pbn);
 
 
-int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr);
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot);
 
 
 int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-19 18:01                     ` [PATCH 2/4] " Bhawanpreet Lakha
@ 2021-10-20  8:34                       ` Jani Nikula
  0 siblings, 0 replies; 37+ messages in thread
From: Jani Nikula @ 2021-10-20  8:34 UTC (permalink / raw)
  To: Bhawanpreet Lakha, Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski,
	Bhawanpreet Lakha

On Tue, 19 Oct 2021, Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> wrote:
> 8b/10b encoding format requires to reserve the first slot for
> recording metadata. Real data transmission starts from the second slot,
> with a total of available 63 slots available.
>
> In 128b/132b encoding format, metadata is transmitted separately
> in LLCP packet before MTP. Real data transmission starts from
> the first slot, with a total of 64 slots available.

Please send the patches as a fresh series instead of replying to the old
thread, it's getting too confusing. Also, please Cc: intel-gfx mailing
list, so you'll get our CI results on it. (Although I'm not sure how
many machines we have with MST setups, but it's better than nothing.)

BR,
Jani.


>
> v2:
> * Move total/start slots to mst_state, and copy it to mst_mgr in
> atomic_check
>
> v3:
> * Only keep the slot info on the mst_state
> * add a start_slot parameter to the payload function, to facilitate non
>   atomic drivers (this is a temporary workaround and should be removed when
>   we are moving out the non atomic driver helpers)
>
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> ---
>  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  2 +-
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 34 ++++++++++++++++---
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  4 +--
>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  2 +-
>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  4 +--
>  include/drm/drm_dp_mst_helper.h               |  5 ++-
>  6 files changed, 40 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index ff0f91c93ba4..6169488e2011 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -251,7 +251,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
>  	}
>  
>  	/* It's OK for this to fail */
> -	drm_dp_update_payload_part1(mst_mgr);
> +	drm_dp_update_payload_part1(mst_mgr, 1);
>  
>  	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
>  	 * AUX message. The sequence is slot 1-63 allocated sequence for each
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 5ab3b3a46e89..d188a5269070 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3353,6 +3353,9 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
>  /**
>   * drm_dp_update_payload_part1() - Execute payload update part 1
>   * @mgr: manager to use.
> + * @start_slot: this is the cur slot
> + *  NOTE: start_slot is a temporary workaround for non-atomic drivers,
> + *  this will be removed when non-atomic mst helpers are moved out of the helper
>   *
>   * This iterates over all proposed virtual channels, and tries to
>   * allocate space in the link for them. For 0->slots transitions,
> @@ -3363,12 +3366,12 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
>   * after calling this the driver should generate ACT and payload
>   * packets.
>   */
> -int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
> +int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot)
>  {
>  	struct drm_dp_payload req_payload;
>  	struct drm_dp_mst_port *port;
>  	int i, j;
> -	int cur_slots = 1;
> +	int cur_slots = start_slot;
>  	bool skip;
>  
>  	mutex_lock(&mgr->payload_lock);
> @@ -4503,6 +4506,26 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
>  }
>  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>  
> +/**
> + * drm_dp_mst_update_slots() - updates the slot info depending on the DP ecoding format
> + * @mst_state: mst_state to update
> + * @link_ecoding_cap: the ecoding format on the link
> + */
> +void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_ecoding_cap)
> +{
> +	if (link_ecoding_cap == DP_CAP_ANSI_128B132B) {
> +		mst_state->total_avail_slots = 64;
> +		mst_state->start_slot = 0;
> +	} else {
> +		mst_state->total_avail_slots = 63;
> +		mst_state->start_slot = 1;
> +	}
> +
> +	DRM_DEBUG_KMS("%s ecoding format on mst_state 0x%p\n",
> +			(link_ecoding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b", mst_state->mgr);
> +}
> +EXPORT_SYMBOL(drm_dp_mst_update_slots);
> +
>  /**
>   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>   * @mgr: manager for this port
> @@ -5222,7 +5245,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
>  					 struct drm_dp_mst_topology_state *mst_state)
>  {
>  	struct drm_dp_vcpi_allocation *vcpi;
> -	int avail_slots = 63, payload_count = 0;
> +	int avail_slots = mst_state->total_avail_slots, payload_count = 0;
>  
>  	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>  		/* Releasing VCPI is always OK-even if the port is gone */
> @@ -5251,7 +5274,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
>  		}
>  	}
>  	drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
> -		       mgr, mst_state, avail_slots, 63 - avail_slots);
> +		       mgr, mst_state, avail_slots, mst_state->total_avail_slots - avail_slots);
>  
>  	return 0;
>  }
> @@ -5528,6 +5551,9 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>  	if (mst_state == NULL)
>  		return -ENOMEM;
>  
> +	mst_state->total_avail_slots = 63;
> +	mst_state->start_slot = 1;
> +
>  	mst_state->mgr = mgr;
>  	INIT_LIST_HEAD(&mst_state->vcpis);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index b170e272bdee..d3a24189a12c 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -368,7 +368,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
>  
>  	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
>  
> -	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> +	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
>  	if (ret) {
>  		drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
>  	}
> @@ -516,7 +516,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
>  
>  	intel_dp->active_mst_links++;
>  
> -	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> +	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
>  
>  	/*
>  	 * Before Gen 12 this is not done as part of
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index f949767698fc..6c8c59c26dbf 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> @@ -1413,7 +1413,7 @@ nv50_mstm_prepare(struct nv50_mstm *mstm)
>  	int ret;
>  
>  	NV_ATOMIC(drm, "%s: mstm prepare\n", mstm->outp->base.base.name);
> -	ret = drm_dp_update_payload_part1(&mstm->mgr);
> +	ret = drm_dp_update_payload_part1(&mstm->mgr, 1);
>  
>  	drm_for_each_encoder(encoder, mstm->outp->base.base.dev) {
>  		if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) {
> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> index ec867fa880a4..751c2c075e09 100644
> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> @@ -423,7 +423,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
>  		drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
>  					 radeon_connector->port,
>  					 mst_enc->pbn, slots);
> -		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
> +		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
>  
>  		radeon_dp_mst_set_be_cntl(primary, mst_enc,
>  					  radeon_connector->mst_port->hpd.hpd, true);
> @@ -452,7 +452,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
>  			return;
>  
>  		drm_dp_mst_reset_vcpi_slots(&radeon_connector->mst_port->mst_mgr, mst_enc->port);
> -		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
> +		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
>  
>  		drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);
>  		/* and this can also fail */
> diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> index ddb9231d0309..3207b49586fc 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
>  	struct drm_private_state base;
>  	struct list_head vcpis;
>  	struct drm_dp_mst_topology_mgr *mgr;
> +	u8 total_avail_slots;
> +	u8 start_slot;
>  };
>  
>  #define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
> @@ -806,6 +808,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
>  
>  void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
>  
> +void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_ecoding_cap);
>  
>  void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>  				struct drm_dp_mst_port *port);
> @@ -815,7 +818,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
>  			   int pbn);
>  
>  
> -int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr);
> +int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot);
>  
>  
>  int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr);

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-03-26  3:14 ` Fangzhi Zuo
@ 2021-03-26 16:48   ` Lyude Paul
  -1 siblings, 0 replies; 37+ messages in thread
From: Lyude Paul @ 2021-03-26 16:48 UTC (permalink / raw)
  To: Fangzhi Zuo, dri-devel, amd-gfx; +Cc: Rodrigo.Siqueira, wayne.lin

On Thu, 2021-03-25 at 23:14 -0400, Fangzhi Zuo wrote:
> 8b/10b encoding format requires to reserve the first slot for
> recording metadata. Real data transmission starts from the second slot,
> with a total of available 63 slots available.
> 
> In 128b/132b encoding format, metadata is transmitted separately
> in LLCP packet before MTP. Real data transmission starts from
> the first slot, with a total of 64 slots available.
> 
> Update the slot information after link detect.
> 
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 48 ++++++++++++++++++++++-----
>  include/drm/drm_dp_mst_helper.h       |  8 +++++
>  2 files changed, 47 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 42a0c6888c33..577ed4224778 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3382,7 +3382,7 @@ int drm_dp_update_payload_part1(struct
> drm_dp_mst_topology_mgr *mgr)
>         struct drm_dp_payload req_payload;
>         struct drm_dp_mst_port *port;
>         int i, j;
> -       int cur_slots = 1;
> +       int cur_slots = mgr->first_link_start_slot;
>  
>         mutex_lock(&mgr->payload_lock);
>         for (i = 0; i < mgr->max_payloads; i++) {
> @@ -4302,8 +4302,13 @@ int drm_dp_find_vcpi_slots(struct
> drm_dp_mst_topology_mgr *mgr,
>  
>         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
>  
> -       /* max. time slots - one slot for MTP header */
> -       if (num_slots > 63)
> +       /**
> +        * first_link_total_avail_slots: max. time slots
> +        * first slot reserved for MTP header in 8b/10b,
> +        * but not required for 128b/132b
> +        */
> +
> +       if (num_slots > mgr->first_link_total_avail_slots)

This is deprecated code, as indicated in the comments for this function. We
really shouldn't be updating this imho.

>                 return -ENOSPC;
>         return num_slots;
>  }
> @@ -4314,8 +4319,12 @@ static int drm_dp_init_vcpi(struct
> drm_dp_mst_topology_mgr *mgr,
>  {
>         int ret;
>  
> -       /* max. time slots - one slot for MTP header */
> -       if (slots > 63)
> +       /**
> +        * first_link_total_avail_slots: max. time slots
> +        * first slot reserved for MTP header in 8b/10b,
> +        * but not required for 128b/132b
> +        */
> +       if (slots > mgr->first_link_total_avail_slots)

why are these kernel docs? putting kdocs in the middle of a function doesn't do
anything

>                 return -ENOSPC;
>  
>         vcpi->pbn = pbn;
> @@ -4488,6 +4497,25 @@ int drm_dp_atomic_release_vcpi_slots(struct
> drm_atomic_state *state,
>  }
>  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>  
> +/*
> + * drm_dp_mst_update_first_link_slot_info()
> + *  update the first link's total available slots and starting slot
> + * @mgr: manager to store the slot info.
> + * @encoding_format: detected link encoding format

These kernel docs aren't properly formatted, follow the examples in the rest of
the file:

/**
 * function() - summary
 * @mgr: something something
 * …
 */

> + */
> +void drm_dp_mst_update_first_link_slot_info(
> +       struct drm_dp_mst_topology_mgr *mgr, uint8_t encoding_format)

Use u8, the kernel discourages using the longer typenames outside of uapi
headers. Also this isn't indented correctly - the kernel doesn't break at the
starting parenthesis for function definitions. This should be something like

drm_dp_mst_update_first_link_slot_info(struct drm_dp_mst_topology_mgr *mgr,
                                       u8 encoding_format)

Also, where is this function actually used? If amdgpu is intending to use this,
it really should be in the same series that this is introduced in so that we can
tell if these helpers are what we really want here or not

> +{
> +       if (encoding_format == DP_CAP_ANSI_128B132B) {
> +               mgr->first_link_total_avail_slots = 64;
> +               mgr->first_link_start_slot = 0;
> +       }
> +       DRM_DEBUG_KMS("%s encoding format on 0x%p -> total %d slots, start at
> slot %d\n",
> +       (encoding_format == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b",
> +               mgr, mgr->first_link_total_avail_slots, mgr-
> >first_link_start_slot);

the indenting here is entirely broken - please follow the same style as the rest
of the file. Line continuations need to start at the beginning parenthesis, but
the lines after DRM_DEBUG_KMS() don't have any additional indenting here.

> +}
> +EXPORT_SYMBOL(drm_dp_mst_update_first_link_slot_info);
> +
>  /**
>   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>   * @mgr: manager for this port
> @@ -4518,8 +4546,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> drm_dp_mst_topology_mgr *mgr,
>  
>         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
>         if (ret) {
> -               DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n",
> -                             DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> +               DRM_DEBUG_KMS("failed to init vcpi slots=%d max=%d ret=%d\n",
> +                       DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> >first_link_total_avail_slots, ret);
>                 drm_dp_mst_topology_put_port(port);
>                 goto out;
>         }
> @@ -5162,7 +5190,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> drm_dp_mst_topology_mgr *mgr,
>                                          struct drm_dp_mst_topology_state
> *mst_state)
>  {
>         struct drm_dp_vcpi_allocation *vcpi;
> -       int avail_slots = 63, payload_count = 0;
> +       int avail_slots = mgr->first_link_total_avail_slots, payload_count =
> 0;
>  
>         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>                 /* Releasing VCPI is always OK-even if the port is gone */
> @@ -5191,7 +5219,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> drm_dp_mst_topology_mgr *mgr,
>         }
>         DRM_DEBUG_ATOMIC("[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
>                          mgr, mst_state, avail_slots,
> -                        63 - avail_slots);
> +                        mgr->first_link_total_avail_slots - avail_slots);
>  
>         return 0;
>  }
> @@ -5455,6 +5483,8 @@ int drm_dp_mst_topology_mgr_init(struct
> drm_dp_mst_topology_mgr *mgr,
>         if (!mgr->proposed_vcpis)
>                 return -ENOMEM;
>         set_bit(0, &mgr->payload_mask);
> +       mgr->first_link_total_avail_slots = 63;
> +       mgr->first_link_start_slot = 1;
>  
>         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>         if (mst_state == NULL)
> diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> index bd1c39907b92..f4310b3705e7 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -653,6 +653,13 @@ struct drm_dp_mst_topology_mgr {
>          */
>         int pbn_div;
>  
> +       /**
> +        * @first_link_total_avail_slots: frist link total slots available.
> +        * @first_link_start_slot: start slot index for real data
> transmission.
> +        */

These kernel docs are also broken, you can't define two variables in the same
kernel doc comment if it's embedded in the struct, there has to be one kernel
doc comment per-member. Attempting to generate documentation with make htmldocs
even mentions this:

./include/drm/drm_dp_mst_helper.h:770: warning: Function parameter or member
'first_link_start_slot' not described in 'drm_dp_mst_topology_mgr'

> +       u8 first_link_total_avail_slots;
> +       u8 first_link_start_slot;
> +
>         /**
>          * @funcs: Atomic helper callbacks
>          */
> @@ -795,6 +802,7 @@ int drm_dp_mst_get_vcpi_slots(struct
> drm_dp_mst_topology_mgr *mgr, struct drm_dp
>  
>  void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct
> drm_dp_mst_port *port);
>  
> +void drm_dp_mst_update_first_link_slot_info(struct drm_dp_mst_topology_mgr
> *mgr, uint8_t encoding_format);
>  
>  void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>                                 struct drm_dp_mst_port *port);

-- 
Sincerely,
   Lyude Paul (she/her)
   Software Engineer at Red Hat
   
Note: I deal with a lot of emails and have a lot of bugs on my plate. If you've
asked me a question, are waiting for a review/merge on a patch, etc. and I
haven't responded in a while, please feel free to send me another email to check
on my status. I don't bite!

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
@ 2021-03-26 16:48   ` Lyude Paul
  0 siblings, 0 replies; 37+ messages in thread
From: Lyude Paul @ 2021-03-26 16:48 UTC (permalink / raw)
  To: Fangzhi Zuo, dri-devel, amd-gfx
  Cc: harry.wentland, Rodrigo.Siqueira, ville.syrjala, wayne.lin

On Thu, 2021-03-25 at 23:14 -0400, Fangzhi Zuo wrote:
> 8b/10b encoding format requires to reserve the first slot for
> recording metadata. Real data transmission starts from the second slot,
> with a total of available 63 slots available.
> 
> In 128b/132b encoding format, metadata is transmitted separately
> in LLCP packet before MTP. Real data transmission starts from
> the first slot, with a total of 64 slots available.
> 
> Update the slot information after link detect.
> 
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 48 ++++++++++++++++++++++-----
>  include/drm/drm_dp_mst_helper.h       |  8 +++++
>  2 files changed, 47 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 42a0c6888c33..577ed4224778 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3382,7 +3382,7 @@ int drm_dp_update_payload_part1(struct
> drm_dp_mst_topology_mgr *mgr)
>         struct drm_dp_payload req_payload;
>         struct drm_dp_mst_port *port;
>         int i, j;
> -       int cur_slots = 1;
> +       int cur_slots = mgr->first_link_start_slot;
>  
>         mutex_lock(&mgr->payload_lock);
>         for (i = 0; i < mgr->max_payloads; i++) {
> @@ -4302,8 +4302,13 @@ int drm_dp_find_vcpi_slots(struct
> drm_dp_mst_topology_mgr *mgr,
>  
>         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
>  
> -       /* max. time slots - one slot for MTP header */
> -       if (num_slots > 63)
> +       /**
> +        * first_link_total_avail_slots: max. time slots
> +        * first slot reserved for MTP header in 8b/10b,
> +        * but not required for 128b/132b
> +        */
> +
> +       if (num_slots > mgr->first_link_total_avail_slots)

This is deprecated code, as indicated in the comments for this function. We
really shouldn't be updating this imho.

>                 return -ENOSPC;
>         return num_slots;
>  }
> @@ -4314,8 +4319,12 @@ static int drm_dp_init_vcpi(struct
> drm_dp_mst_topology_mgr *mgr,
>  {
>         int ret;
>  
> -       /* max. time slots - one slot for MTP header */
> -       if (slots > 63)
> +       /**
> +        * first_link_total_avail_slots: max. time slots
> +        * first slot reserved for MTP header in 8b/10b,
> +        * but not required for 128b/132b
> +        */
> +       if (slots > mgr->first_link_total_avail_slots)

why are these kernel docs? putting kdocs in the middle of a function doesn't do
anything

>                 return -ENOSPC;
>  
>         vcpi->pbn = pbn;
> @@ -4488,6 +4497,25 @@ int drm_dp_atomic_release_vcpi_slots(struct
> drm_atomic_state *state,
>  }
>  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
>  
> +/*
> + * drm_dp_mst_update_first_link_slot_info()
> + *  update the first link's total available slots and starting slot
> + * @mgr: manager to store the slot info.
> + * @encoding_format: detected link encoding format

These kernel docs aren't properly formatted, follow the examples in the rest of
the file:

/**
 * function() - summary
 * @mgr: something something
 * …
 */

> + */
> +void drm_dp_mst_update_first_link_slot_info(
> +       struct drm_dp_mst_topology_mgr *mgr, uint8_t encoding_format)

Use u8, the kernel discourages using the longer typenames outside of uapi
headers. Also this isn't indented correctly - the kernel doesn't break at the
starting parenthesis for function definitions. This should be something like

drm_dp_mst_update_first_link_slot_info(struct drm_dp_mst_topology_mgr *mgr,
                                       u8 encoding_format)

Also, where is this function actually used? If amdgpu is intending to use this,
it really should be in the same series that this is introduced in so that we can
tell if these helpers are what we really want here or not

> +{
> +       if (encoding_format == DP_CAP_ANSI_128B132B) {
> +               mgr->first_link_total_avail_slots = 64;
> +               mgr->first_link_start_slot = 0;
> +       }
> +       DRM_DEBUG_KMS("%s encoding format on 0x%p -> total %d slots, start at
> slot %d\n",
> +       (encoding_format == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b",
> +               mgr, mgr->first_link_total_avail_slots, mgr-
> >first_link_start_slot);

the indenting here is entirely broken - please follow the same style as the rest
of the file. Line continuations need to start at the beginning parenthesis, but
the lines after DRM_DEBUG_KMS() don't have any additional indenting here.

> +}
> +EXPORT_SYMBOL(drm_dp_mst_update_first_link_slot_info);
> +
>  /**
>   * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
>   * @mgr: manager for this port
> @@ -4518,8 +4546,8 @@ bool drm_dp_mst_allocate_vcpi(struct
> drm_dp_mst_topology_mgr *mgr,
>  
>         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
>         if (ret) {
> -               DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n",
> -                             DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
> +               DRM_DEBUG_KMS("failed to init vcpi slots=%d max=%d ret=%d\n",
> +                       DIV_ROUND_UP(pbn, mgr->pbn_div), mgr-
> >first_link_total_avail_slots, ret);
>                 drm_dp_mst_topology_put_port(port);
>                 goto out;
>         }
> @@ -5162,7 +5190,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> drm_dp_mst_topology_mgr *mgr,
>                                          struct drm_dp_mst_topology_state
> *mst_state)
>  {
>         struct drm_dp_vcpi_allocation *vcpi;
> -       int avail_slots = 63, payload_count = 0;
> +       int avail_slots = mgr->first_link_total_avail_slots, payload_count =
> 0;
>  
>         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
>                 /* Releasing VCPI is always OK-even if the port is gone */
> @@ -5191,7 +5219,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct
> drm_dp_mst_topology_mgr *mgr,
>         }
>         DRM_DEBUG_ATOMIC("[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
>                          mgr, mst_state, avail_slots,
> -                        63 - avail_slots);
> +                        mgr->first_link_total_avail_slots - avail_slots);
>  
>         return 0;
>  }
> @@ -5455,6 +5483,8 @@ int drm_dp_mst_topology_mgr_init(struct
> drm_dp_mst_topology_mgr *mgr,
>         if (!mgr->proposed_vcpis)
>                 return -ENOMEM;
>         set_bit(0, &mgr->payload_mask);
> +       mgr->first_link_total_avail_slots = 63;
> +       mgr->first_link_start_slot = 1;
>  
>         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
>         if (mst_state == NULL)
> diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> index bd1c39907b92..f4310b3705e7 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -653,6 +653,13 @@ struct drm_dp_mst_topology_mgr {
>          */
>         int pbn_div;
>  
> +       /**
> +        * @first_link_total_avail_slots: frist link total slots available.
> +        * @first_link_start_slot: start slot index for real data
> transmission.
> +        */

These kernel docs are also broken, you can't define two variables in the same
kernel doc comment if it's embedded in the struct, there has to be one kernel
doc comment per-member. Attempting to generate documentation with make htmldocs
even mentions this:

./include/drm/drm_dp_mst_helper.h:770: warning: Function parameter or member
'first_link_start_slot' not described in 'drm_dp_mst_topology_mgr'

> +       u8 first_link_total_avail_slots;
> +       u8 first_link_start_slot;
> +
>         /**
>          * @funcs: Atomic helper callbacks
>          */
> @@ -795,6 +802,7 @@ int drm_dp_mst_get_vcpi_slots(struct
> drm_dp_mst_topology_mgr *mgr, struct drm_dp
>  
>  void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct
> drm_dp_mst_port *port);
>  
> +void drm_dp_mst_update_first_link_slot_info(struct drm_dp_mst_topology_mgr
> *mgr, uint8_t encoding_format);
>  
>  void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
>                                 struct drm_dp_mst_port *port);

-- 
Sincerely,
   Lyude Paul (she/her)
   Software Engineer at Red Hat
   
Note: I deal with a lot of emails and have a lot of bugs on my plate. If you've
asked me a question, are waiting for a review/merge on a patch, etc. and I
haven't responded in a while, please feel free to send me another email to check
on my status. I don't bite!

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
@ 2021-03-26  3:14 ` Fangzhi Zuo
  0 siblings, 0 replies; 37+ messages in thread
From: Fangzhi Zuo @ 2021-03-26  3:14 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Rodrigo.Siqueira, Fangzhi Zuo, wayne.lin

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

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

Update the slot information after link detect.

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 48 ++++++++++++++++++++++-----
 include/drm/drm_dp_mst_helper.h       |  8 +++++
 2 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 42a0c6888c33..577ed4224778 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3382,7 +3382,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
 	struct drm_dp_payload req_payload;
 	struct drm_dp_mst_port *port;
 	int i, j;
-	int cur_slots = 1;
+	int cur_slots = mgr->first_link_start_slot;
 
 	mutex_lock(&mgr->payload_lock);
 	for (i = 0; i < mgr->max_payloads; i++) {
@@ -4302,8 +4302,13 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
 
 	num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
 
-	/* max. time slots - one slot for MTP header */
-	if (num_slots > 63)
+	/**
+	 * first_link_total_avail_slots: max. time slots
+	 * first slot reserved for MTP header in 8b/10b,
+	 * but not required for 128b/132b
+	 */
+
+	if (num_slots > mgr->first_link_total_avail_slots)
 		return -ENOSPC;
 	return num_slots;
 }
@@ -4314,8 +4319,12 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 {
 	int ret;
 
-	/* max. time slots - one slot for MTP header */
-	if (slots > 63)
+	/**
+	 * first_link_total_avail_slots: max. time slots
+	 * first slot reserved for MTP header in 8b/10b,
+	 * but not required for 128b/132b
+	 */
+	if (slots > mgr->first_link_total_avail_slots)
 		return -ENOSPC;
 
 	vcpi->pbn = pbn;
@@ -4488,6 +4497,25 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 
+/*
+ * drm_dp_mst_update_first_link_slot_info()
+ *  update the first link's total available slots and starting slot
+ * @mgr: manager to store the slot info.
+ * @encoding_format: detected link encoding format
+ */
+void drm_dp_mst_update_first_link_slot_info(
+	struct drm_dp_mst_topology_mgr *mgr, uint8_t encoding_format)
+{
+	if (encoding_format == DP_CAP_ANSI_128B132B) {
+		mgr->first_link_total_avail_slots = 64;
+		mgr->first_link_start_slot = 0;
+	}
+	DRM_DEBUG_KMS("%s encoding format on 0x%p -> total %d slots, start at slot %d\n",
+	(encoding_format == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b",
+		mgr, mgr->first_link_total_avail_slots, mgr->first_link_start_slot);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_first_link_slot_info);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -4518,8 +4546,8 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 
 	ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
 	if (ret) {
-		DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n",
-			      DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
+		DRM_DEBUG_KMS("failed to init vcpi slots=%d max=%d ret=%d\n",
+			DIV_ROUND_UP(pbn, mgr->pbn_div), mgr->first_link_total_avail_slots, ret);
 		drm_dp_mst_topology_put_port(port);
 		goto out;
 	}
@@ -5162,7 +5190,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 					 struct drm_dp_mst_topology_state *mst_state)
 {
 	struct drm_dp_vcpi_allocation *vcpi;
-	int avail_slots = 63, payload_count = 0;
+	int avail_slots = mgr->first_link_total_avail_slots, payload_count = 0;
 
 	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
 		/* Releasing VCPI is always OK-even if the port is gone */
@@ -5191,7 +5219,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 	}
 	DRM_DEBUG_ATOMIC("[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
 			 mgr, mst_state, avail_slots,
-			 63 - avail_slots);
+			 mgr->first_link_total_avail_slots - avail_slots);
 
 	return 0;
 }
@@ -5455,6 +5483,8 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	if (!mgr->proposed_vcpis)
 		return -ENOMEM;
 	set_bit(0, &mgr->payload_mask);
+	mgr->first_link_total_avail_slots = 63;
+	mgr->first_link_start_slot = 1;
 
 	mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
 	if (mst_state == NULL)
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index bd1c39907b92..f4310b3705e7 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -653,6 +653,13 @@ struct drm_dp_mst_topology_mgr {
 	 */
 	int pbn_div;
 
+	/**
+	 * @first_link_total_avail_slots: frist link total slots available.
+	 * @first_link_start_slot: start slot index for real data transmission.
+	 */
+	u8 first_link_total_avail_slots;
+	u8 first_link_start_slot;
+
 	/**
 	 * @funcs: Atomic helper callbacks
 	 */
@@ -795,6 +802,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
 
 void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
+void drm_dp_mst_update_first_link_slot_info(struct drm_dp_mst_topology_mgr *mgr, uint8_t encoding_format);
 
 void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 				struct drm_dp_mst_port *port);
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format
@ 2021-03-26  3:14 ` Fangzhi Zuo
  0 siblings, 0 replies; 37+ messages in thread
From: Fangzhi Zuo @ 2021-03-26  3:14 UTC (permalink / raw)
  To: dri-devel, amd-gfx
  Cc: Rodrigo.Siqueira, Fangzhi Zuo, wayne.lin, harry.wentland, ville.syrjala

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

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

Update the slot information after link detect.

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 48 ++++++++++++++++++++++-----
 include/drm/drm_dp_mst_helper.h       |  8 +++++
 2 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 42a0c6888c33..577ed4224778 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3382,7 +3382,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
 	struct drm_dp_payload req_payload;
 	struct drm_dp_mst_port *port;
 	int i, j;
-	int cur_slots = 1;
+	int cur_slots = mgr->first_link_start_slot;
 
 	mutex_lock(&mgr->payload_lock);
 	for (i = 0; i < mgr->max_payloads; i++) {
@@ -4302,8 +4302,13 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
 
 	num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
 
-	/* max. time slots - one slot for MTP header */
-	if (num_slots > 63)
+	/**
+	 * first_link_total_avail_slots: max. time slots
+	 * first slot reserved for MTP header in 8b/10b,
+	 * but not required for 128b/132b
+	 */
+
+	if (num_slots > mgr->first_link_total_avail_slots)
 		return -ENOSPC;
 	return num_slots;
 }
@@ -4314,8 +4319,12 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 {
 	int ret;
 
-	/* max. time slots - one slot for MTP header */
-	if (slots > 63)
+	/**
+	 * first_link_total_avail_slots: max. time slots
+	 * first slot reserved for MTP header in 8b/10b,
+	 * but not required for 128b/132b
+	 */
+	if (slots > mgr->first_link_total_avail_slots)
 		return -ENOSPC;
 
 	vcpi->pbn = pbn;
@@ -4488,6 +4497,25 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 
+/*
+ * drm_dp_mst_update_first_link_slot_info()
+ *  update the first link's total available slots and starting slot
+ * @mgr: manager to store the slot info.
+ * @encoding_format: detected link encoding format
+ */
+void drm_dp_mst_update_first_link_slot_info(
+	struct drm_dp_mst_topology_mgr *mgr, uint8_t encoding_format)
+{
+	if (encoding_format == DP_CAP_ANSI_128B132B) {
+		mgr->first_link_total_avail_slots = 64;
+		mgr->first_link_start_slot = 0;
+	}
+	DRM_DEBUG_KMS("%s encoding format on 0x%p -> total %d slots, start at slot %d\n",
+	(encoding_format == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b",
+		mgr, mgr->first_link_total_avail_slots, mgr->first_link_start_slot);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_first_link_slot_info);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -4518,8 +4546,8 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 
 	ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
 	if (ret) {
-		DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n",
-			      DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
+		DRM_DEBUG_KMS("failed to init vcpi slots=%d max=%d ret=%d\n",
+			DIV_ROUND_UP(pbn, mgr->pbn_div), mgr->first_link_total_avail_slots, ret);
 		drm_dp_mst_topology_put_port(port);
 		goto out;
 	}
@@ -5162,7 +5190,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 					 struct drm_dp_mst_topology_state *mst_state)
 {
 	struct drm_dp_vcpi_allocation *vcpi;
-	int avail_slots = 63, payload_count = 0;
+	int avail_slots = mgr->first_link_total_avail_slots, payload_count = 0;
 
 	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
 		/* Releasing VCPI is always OK-even if the port is gone */
@@ -5191,7 +5219,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 	}
 	DRM_DEBUG_ATOMIC("[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
 			 mgr, mst_state, avail_slots,
-			 63 - avail_slots);
+			 mgr->first_link_total_avail_slots - avail_slots);
 
 	return 0;
 }
@@ -5455,6 +5483,8 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	if (!mgr->proposed_vcpis)
 		return -ENOMEM;
 	set_bit(0, &mgr->payload_mask);
+	mgr->first_link_total_avail_slots = 63;
+	mgr->first_link_start_slot = 1;
 
 	mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
 	if (mst_state == NULL)
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index bd1c39907b92..f4310b3705e7 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -653,6 +653,13 @@ struct drm_dp_mst_topology_mgr {
 	 */
 	int pbn_div;
 
+	/**
+	 * @first_link_total_avail_slots: frist link total slots available.
+	 * @first_link_start_slot: start slot index for real data transmission.
+	 */
+	u8 first_link_total_avail_slots;
+	u8 first_link_start_slot;
+
 	/**
 	 * @funcs: Atomic helper callbacks
 	 */
@@ -795,6 +802,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
 
 void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
+void drm_dp_mst_update_first_link_slot_info(struct drm_dp_mst_topology_mgr *mgr, uint8_t encoding_format);
 
 void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 				struct drm_dp_mst_port *port);
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2021-10-20  8:34 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-27 23:43 [PATCH 0/2] Update 128b/132b MST Slot Information Fangzhi Zuo
2021-08-27 23:43 ` [PATCH 1/2] drm: Update MST First Link Slot Information Based on Encoding Format Fangzhi Zuo
2021-08-28  4:09   ` kernel test robot
2021-08-28  4:09     ` kernel test robot
2021-08-30 20:00   ` Lyude Paul
2021-08-31 19:44     ` Zuo, Jerry
2021-08-31 20:19       ` Lyude Paul
2021-08-31 22:44       ` Lyude Paul
2021-10-12 21:58         ` [PATCH] " Bhawanpreet Lakha
2021-10-12 22:02           ` Lakha, Bhawanpreet
2021-10-12 22:09             ` Lyude Paul
2021-10-13 16:09           ` Jani Nikula
2021-10-13 19:33             ` Bhawanpreet Lakha
2021-10-13 19:37               ` Lyude Paul
2021-10-13 18:52           ` kernel test robot
2021-10-13 18:52             ` kernel test robot
2021-10-13 21:54           ` kernel test robot
2021-10-13 21:54             ` kernel test robot
2021-10-13 22:25           ` Lyude Paul
2021-10-14 20:21             ` Bhawanpreet Lakha
2021-10-14 20:22               ` Bhawanpreet Lakha
2021-10-15 20:04               ` Lyude Paul
2021-10-15 19:43             ` Bhawanpreet Lakha
2021-10-15 20:41               ` Lyude Paul
2021-10-18 19:47                 ` Bhawanpreet Lakha
2021-10-18 23:17                   ` Lyude Paul
2021-10-19 18:01                     ` [PATCH 2/4] " Bhawanpreet Lakha
2021-10-20  8:34                       ` Jani Nikula
2021-08-31 22:45       ` [PATCH 1/2] " Lyude Paul
2021-08-31 22:46         ` Lyude Paul
2021-08-27 23:43 ` [PATCH 2/2] drm/amdgpu: Example Usage in AMDGPU Fangzhi Zuo
2021-08-28 11:54   ` kernel test robot
2021-08-28 11:54     ` kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2021-03-26  3:14 [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format Fangzhi Zuo
2021-03-26  3:14 ` Fangzhi Zuo
2021-03-26 16:48 ` Lyude Paul
2021-03-26 16:48   ` Lyude Paul

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.