mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
Short summary of fixes pull:
Contains fixes for DP MST and the panel orientation on an Lenovo IdeaPad model. -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmPuB6cACgkQaA3BHVML eiNrgwf+Of4L65lpUbMtqfXygfIvy++rzMJuB06+ccmXA3j/QLiAftLVEEtwJpfm 9nn3Fmu0tBE9i3ULkiVUDOizP76EjNXewWSfPl730NJ1+Y6/h0/ljdCeQDNLxts7 QkZkm7FgIldP2rNN4P84VMz60A6m8B8C60N64+ucFdNtd7+67jhLdwHpP1/gwkKS idwMGcfVfV37PnSUCdXvfYUWpKZZ1xiUkR+0twjWR//8pEEekSRBsiF3l/gyJqK0 u80myF4ph+yvfdLuerFFqHdVtSVzSiCcziuiIMdn5t5d03MxVlD6C/pCfExbwBmi D0VthHzn215rRdOlaApLL9FlzbvnhA== =g76M -----END PGP SIGNATURE----- Merge tag 'drm-misc-next-fixes-2023-02-16' of git://anongit.freedesktop.org/drm/drm-misc into drm-next Short summary of fixes pull: Contains fixes for DP MST and the panel orientation on an Lenovo IdeaPad model. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/Y+4H4C4E6cZcM9+J@linux-uq9g
This commit is contained in:
commit
ef04277600
@ -208,7 +208,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
|
||||
if (enable)
|
||||
drm_dp_add_payload_part1(mst_mgr, mst_state, payload);
|
||||
else
|
||||
drm_dp_remove_payload(mst_mgr, mst_state, payload);
|
||||
drm_dp_remove_payload(mst_mgr, mst_state, payload, payload);
|
||||
|
||||
/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
|
||||
* AUX message. The sequence is slot 1-63 allocated sequence for each
|
||||
|
@ -3342,7 +3342,8 @@ EXPORT_SYMBOL(drm_dp_add_payload_part1);
|
||||
* drm_dp_remove_payload() - Remove an MST payload
|
||||
* @mgr: Manager to use.
|
||||
* @mst_state: The MST atomic state
|
||||
* @payload: The payload to write
|
||||
* @old_payload: The payload with its old state
|
||||
* @new_payload: The payload to write
|
||||
*
|
||||
* Removes a payload from an MST topology if it was successfully assigned a start slot. Also updates
|
||||
* the starting time slots of all other payloads which would have been shifted towards the start of
|
||||
@ -3350,36 +3351,37 @@ EXPORT_SYMBOL(drm_dp_add_payload_part1);
|
||||
*/
|
||||
void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr,
|
||||
struct drm_dp_mst_topology_state *mst_state,
|
||||
struct drm_dp_mst_atomic_payload *payload)
|
||||
const struct drm_dp_mst_atomic_payload *old_payload,
|
||||
struct drm_dp_mst_atomic_payload *new_payload)
|
||||
{
|
||||
struct drm_dp_mst_atomic_payload *pos;
|
||||
bool send_remove = false;
|
||||
|
||||
/* We failed to make the payload, so nothing to do */
|
||||
if (payload->vc_start_slot == -1)
|
||||
if (new_payload->vc_start_slot == -1)
|
||||
return;
|
||||
|
||||
mutex_lock(&mgr->lock);
|
||||
send_remove = drm_dp_mst_port_downstream_of_branch(payload->port, mgr->mst_primary);
|
||||
send_remove = drm_dp_mst_port_downstream_of_branch(new_payload->port, mgr->mst_primary);
|
||||
mutex_unlock(&mgr->lock);
|
||||
|
||||
if (send_remove)
|
||||
drm_dp_destroy_payload_step1(mgr, mst_state, payload);
|
||||
drm_dp_destroy_payload_step1(mgr, mst_state, new_payload);
|
||||
else
|
||||
drm_dbg_kms(mgr->dev, "Payload for VCPI %d not in topology, not sending remove\n",
|
||||
payload->vcpi);
|
||||
new_payload->vcpi);
|
||||
|
||||
list_for_each_entry(pos, &mst_state->payloads, next) {
|
||||
if (pos != payload && pos->vc_start_slot > payload->vc_start_slot)
|
||||
pos->vc_start_slot -= payload->time_slots;
|
||||
if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)
|
||||
pos->vc_start_slot -= old_payload->time_slots;
|
||||
}
|
||||
payload->vc_start_slot = -1;
|
||||
new_payload->vc_start_slot = -1;
|
||||
|
||||
mgr->payload_count--;
|
||||
mgr->next_start_slot -= payload->time_slots;
|
||||
mgr->next_start_slot -= old_payload->time_slots;
|
||||
|
||||
if (payload->delete)
|
||||
drm_dp_mst_put_port_malloc(payload->port);
|
||||
if (new_payload->delete)
|
||||
drm_dp_mst_put_port_malloc(new_payload->port);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_remove_payload);
|
||||
|
||||
@ -5363,27 +5365,52 @@ struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_a
|
||||
EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
|
||||
|
||||
/**
|
||||
* drm_atomic_get_new_mst_topology_state: get new MST topology state in atomic state, if any
|
||||
* drm_atomic_get_old_mst_topology_state: get old MST topology state in atomic state, if any
|
||||
* @state: global atomic state
|
||||
* @mgr: MST topology manager, also the private object in this case
|
||||
*
|
||||
* This function wraps drm_atomic_get_priv_obj_state() passing in the MST atomic
|
||||
* This function wraps drm_atomic_get_old_private_obj_state() passing in the MST atomic
|
||||
* state vtable so that the private object state returned is that of a MST
|
||||
* topology object.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* The MST topology state, or NULL if there's no topology state for this MST mgr
|
||||
* The old MST topology state, or NULL if there's no topology state for this MST mgr
|
||||
* in the global atomic state
|
||||
*/
|
||||
struct drm_dp_mst_topology_state *
|
||||
drm_atomic_get_old_mst_topology_state(struct drm_atomic_state *state,
|
||||
struct drm_dp_mst_topology_mgr *mgr)
|
||||
{
|
||||
struct drm_private_state *old_priv_state =
|
||||
drm_atomic_get_old_private_obj_state(state, &mgr->base);
|
||||
|
||||
return old_priv_state ? to_dp_mst_topology_state(old_priv_state) : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_get_old_mst_topology_state);
|
||||
|
||||
/**
|
||||
* drm_atomic_get_new_mst_topology_state: get new MST topology state in atomic state, if any
|
||||
* @state: global atomic state
|
||||
* @mgr: MST topology manager, also the private object in this case
|
||||
*
|
||||
* This function wraps drm_atomic_get_new_private_obj_state() passing in the MST atomic
|
||||
* state vtable so that the private object state returned is that of a MST
|
||||
* topology object.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* The new MST topology state, or NULL if there's no topology state for this MST mgr
|
||||
* in the global atomic state
|
||||
*/
|
||||
struct drm_dp_mst_topology_state *
|
||||
drm_atomic_get_new_mst_topology_state(struct drm_atomic_state *state,
|
||||
struct drm_dp_mst_topology_mgr *mgr)
|
||||
{
|
||||
struct drm_private_state *priv_state =
|
||||
struct drm_private_state *new_priv_state =
|
||||
drm_atomic_get_new_private_obj_state(state, &mgr->base);
|
||||
|
||||
return priv_state ? to_dp_mst_topology_state(priv_state) : NULL;
|
||||
return new_priv_state ? to_dp_mst_topology_state(new_priv_state) : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_get_new_mst_topology_state);
|
||||
|
||||
|
@ -322,6 +322,12 @@ static const struct dmi_system_id orientation_data[] = {
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGL"),
|
||||
},
|
||||
.driver_data = (void *)&lcd800x1280_rightside_up,
|
||||
}, { /* Lenovo IdeaPad Duet 3 10IGL5 */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"),
|
||||
},
|
||||
.driver_data = (void *)&lcd1200x1920_rightside_up,
|
||||
}, { /* Lenovo Yoga Book X90F / X91F / X91L */
|
||||
.matches = {
|
||||
/* Non exact match to match all versions */
|
||||
|
@ -5934,6 +5934,10 @@ int intel_modeset_all_pipes(struct intel_atomic_state *state,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = intel_dp_mst_add_topology_state_for_crtc(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = intel_atomic_add_affected_planes(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -524,8 +524,14 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
|
||||
struct intel_dp *intel_dp = &dig_port->dp;
|
||||
struct intel_connector *connector =
|
||||
to_intel_connector(old_conn_state->connector);
|
||||
struct drm_dp_mst_topology_state *mst_state =
|
||||
drm_atomic_get_mst_topology_state(&state->base, &intel_dp->mst_mgr);
|
||||
struct drm_dp_mst_topology_state *old_mst_state =
|
||||
drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
|
||||
struct drm_dp_mst_topology_state *new_mst_state =
|
||||
drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
|
||||
const struct drm_dp_mst_atomic_payload *old_payload =
|
||||
drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
|
||||
struct drm_dp_mst_atomic_payload *new_payload =
|
||||
drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
|
||||
drm_dbg_kms(&i915->drm, "active links %d\n",
|
||||
@ -533,8 +539,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
|
||||
|
||||
intel_hdcp_disable(intel_mst->connector);
|
||||
|
||||
drm_dp_remove_payload(&intel_dp->mst_mgr, mst_state,
|
||||
drm_atomic_get_mst_payload_state(mst_state, connector->port));
|
||||
drm_dp_remove_payload(&intel_dp->mst_mgr, new_mst_state,
|
||||
old_payload, new_payload);
|
||||
|
||||
intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
|
||||
}
|
||||
@ -1223,3 +1229,64 @@ bool intel_dp_mst_is_slave_trans(const struct intel_crtc_state *crtc_state)
|
||||
return crtc_state->mst_master_transcoder != INVALID_TRANSCODER &&
|
||||
crtc_state->mst_master_transcoder != crtc_state->cpu_transcoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dp_mst_add_topology_state_for_connector - add MST topology state for a connector
|
||||
* @state: atomic state
|
||||
* @connector: connector to add the state for
|
||||
* @crtc: the CRTC @connector is attached to
|
||||
*
|
||||
* Add the MST topology state for @connector to @state.
|
||||
*
|
||||
* Returns 0 on success, negative error code on failure.
|
||||
*/
|
||||
static int
|
||||
intel_dp_mst_add_topology_state_for_connector(struct intel_atomic_state *state,
|
||||
struct intel_connector *connector,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_dp_mst_topology_state *mst_state;
|
||||
|
||||
if (!connector->mst_port)
|
||||
return 0;
|
||||
|
||||
mst_state = drm_atomic_get_mst_topology_state(&state->base,
|
||||
&connector->mst_port->mst_mgr);
|
||||
if (IS_ERR(mst_state))
|
||||
return PTR_ERR(mst_state);
|
||||
|
||||
mst_state->pending_crtc_mask |= drm_crtc_mask(&crtc->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dp_mst_add_topology_state_for_crtc - add MST topology state for a CRTC
|
||||
* @state: atomic state
|
||||
* @crtc: CRTC to add the state for
|
||||
*
|
||||
* Add the MST topology state for @crtc to @state.
|
||||
*
|
||||
* Returns 0 on success, negative error code on failure.
|
||||
*/
|
||||
int intel_dp_mst_add_topology_state_for_crtc(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_connector *_connector;
|
||||
struct drm_connector_state *conn_state;
|
||||
int i;
|
||||
|
||||
for_each_new_connector_in_state(&state->base, _connector, conn_state, i) {
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
int ret;
|
||||
|
||||
if (conn_state->crtc != &crtc->base)
|
||||
continue;
|
||||
|
||||
ret = intel_dp_mst_add_topology_state_for_connector(state, connector, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct intel_atomic_state;
|
||||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
struct intel_digital_port;
|
||||
struct intel_dp;
|
||||
@ -18,5 +20,7 @@ int intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port);
|
||||
bool intel_dp_mst_is_master_trans(const struct intel_crtc_state *crtc_state);
|
||||
bool intel_dp_mst_is_slave_trans(const struct intel_crtc_state *crtc_state);
|
||||
bool intel_dp_mst_source_support(struct intel_dp *intel_dp);
|
||||
int intel_dp_mst_add_topology_state_for_crtc(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
|
||||
#endif /* __INTEL_DP_MST_H__ */
|
||||
|
@ -885,7 +885,7 @@ nv50_msto_prepare(struct drm_atomic_state *state,
|
||||
|
||||
// TODO: Figure out if we want to do a better job of handling VCPI allocation failures here?
|
||||
if (msto->disabled) {
|
||||
drm_dp_remove_payload(mgr, mst_state, payload);
|
||||
drm_dp_remove_payload(mgr, mst_state, payload, payload);
|
||||
|
||||
nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index, 0, 0, 0, 0);
|
||||
} else {
|
||||
|
@ -841,7 +841,8 @@ int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
|
||||
struct drm_dp_mst_atomic_payload *payload);
|
||||
void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr,
|
||||
struct drm_dp_mst_topology_state *mst_state,
|
||||
struct drm_dp_mst_atomic_payload *payload);
|
||||
const struct drm_dp_mst_atomic_payload *old_payload,
|
||||
struct drm_dp_mst_atomic_payload *new_payload);
|
||||
|
||||
int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
|
||||
|
||||
@ -867,6 +868,9 @@ struct drm_dp_mst_topology_state *
|
||||
drm_atomic_get_mst_topology_state(struct drm_atomic_state *state,
|
||||
struct drm_dp_mst_topology_mgr *mgr);
|
||||
struct drm_dp_mst_topology_state *
|
||||
drm_atomic_get_old_mst_topology_state(struct drm_atomic_state *state,
|
||||
struct drm_dp_mst_topology_mgr *mgr);
|
||||
struct drm_dp_mst_topology_state *
|
||||
drm_atomic_get_new_mst_topology_state(struct drm_atomic_state *state,
|
||||
struct drm_dp_mst_topology_mgr *mgr);
|
||||
struct drm_dp_mst_atomic_payload *
|
||||
|
Loading…
Reference in New Issue
Block a user