Commit d6c6a76f authored by Bhawanpreet Lakha's avatar Bhawanpreet Lakha Committed by Lyude Paul

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:
* 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)

v4:
*fixed typo and formatting

v5: (no functional changes)
* Fixed formatting in drm_dp_mst_update_slots()
* Reference mst_state instead of mst_state->mgr for debugging info
Signed-off-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarFangzhi Zuo <Jerry.Zuo@amd.com>
[v5 nitpicks]
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
Signed-off-by: default avatarLyude Paul <lyude@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211025223825.301703-3-lyude@redhat.com
parent 03320783
...@@ -251,7 +251,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( ...@@ -251,7 +251,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
} }
/* It's OK for this to fail */ /* 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 /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
* AUX message. The sequence is slot 1-63 allocated sequence for each * AUX message. The sequence is slot 1-63 allocated sequence for each
......
...@@ -3355,6 +3355,10 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr, ...@@ -3355,6 +3355,10 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
/** /**
* drm_dp_update_payload_part1() - Execute payload update part 1 * drm_dp_update_payload_part1() - Execute payload update part 1
* @mgr: manager to use. * @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 * This iterates over all proposed virtual channels, and tries to
* allocate space in the link for them. For 0->slots transitions, * allocate space in the link for them. For 0->slots transitions,
...@@ -3365,12 +3369,12 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr, ...@@ -3365,12 +3369,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 * after calling this the driver should generate ACT and payload
* packets. * 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_payload req_payload;
struct drm_dp_mst_port *port; struct drm_dp_mst_port *port;
int i, j; int i, j;
int cur_slots = 1; int cur_slots = start_slot;
bool skip; bool skip;
mutex_lock(&mgr->payload_lock); mutex_lock(&mgr->payload_lock);
...@@ -4505,6 +4509,27 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, ...@@ -4505,6 +4509,27 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
} }
EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots); 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_encoding_cap: the ecoding format on the link
*/
void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap)
{
if (link_encoding_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 encoding format on mst_state 0x%p\n",
(link_encoding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b",
mst_state);
}
EXPORT_SYMBOL(drm_dp_mst_update_slots);
/** /**
* drm_dp_mst_allocate_vcpi() - Allocate a virtual channel * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
* @mgr: manager for this port * @mgr: manager for this port
...@@ -5224,7 +5249,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr, ...@@ -5224,7 +5249,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_mst_topology_state *mst_state)
{ {
struct drm_dp_vcpi_allocation *vcpi; 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) { list_for_each_entry(vcpi, &mst_state->vcpis, next) {
/* Releasing VCPI is always OK-even if the port is gone */ /* Releasing VCPI is always OK-even if the port is gone */
...@@ -5253,7 +5278,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr, ...@@ -5253,7 +5278,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", 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; return 0;
} }
...@@ -5530,6 +5555,9 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, ...@@ -5530,6 +5555,9 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
if (mst_state == NULL) if (mst_state == NULL)
return -ENOMEM; return -ENOMEM;
mst_state->total_avail_slots = 63;
mst_state->start_slot = 1;
mst_state->mgr = mgr; mst_state->mgr = mgr;
INIT_LIST_HEAD(&mst_state->vcpis); INIT_LIST_HEAD(&mst_state->vcpis);
......
...@@ -378,7 +378,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state, ...@@ -378,7 +378,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port); 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) { if (ret) {
drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret); drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
} }
...@@ -518,7 +518,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, ...@@ -518,7 +518,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
intel_dp->active_mst_links++; 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 * Before Gen 12 this is not done as part of
......
...@@ -1414,7 +1414,7 @@ nv50_mstm_prepare(struct nv50_mstm *mstm) ...@@ -1414,7 +1414,7 @@ nv50_mstm_prepare(struct nv50_mstm *mstm)
int ret; int ret;
NV_ATOMIC(drm, "%s: mstm prepare\n", mstm->outp->base.base.name); 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) { drm_for_each_encoder(encoder, mstm->outp->base.base.dev) {
if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) { if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) {
......
...@@ -423,7 +423,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode) ...@@ -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, drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
radeon_connector->port, radeon_connector->port,
mst_enc->pbn, slots); 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_dp_mst_set_be_cntl(primary, mst_enc,
radeon_connector->mst_port->hpd.hpd, true); radeon_connector->mst_port->hpd.hpd, true);
...@@ -452,7 +452,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode) ...@@ -452,7 +452,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
return; return;
drm_dp_mst_reset_vcpi_slots(&radeon_connector->mst_port->mst_mgr, mst_enc->port); 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); drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);
/* and this can also fail */ /* and this can also fail */
......
...@@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state { ...@@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
struct drm_private_state base; struct drm_private_state base;
struct list_head vcpis; struct list_head vcpis;
struct drm_dp_mst_topology_mgr *mgr; 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) #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 ...@@ -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_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_encoding_cap);
void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
struct drm_dp_mst_port *port); struct drm_dp_mst_port *port);
...@@ -815,7 +818,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, ...@@ -815,7 +818,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
int pbn); 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); int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment