Skip to content

Commit ef04277

Browse files
committed
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 <[email protected]> From: Thomas Zimmermann <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/Y+4H4C4E6cZcM9+J@linux-uq9g
2 parents 8573df3 + 38b2d8e commit ef04277

File tree

8 files changed

+135
-23
lines changed

8 files changed

+135
-23
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
208208
if (enable)
209209
drm_dp_add_payload_part1(mst_mgr, mst_state, payload);
210210
else
211-
drm_dp_remove_payload(mst_mgr, mst_state, payload);
211+
drm_dp_remove_payload(mst_mgr, mst_state, payload, payload);
212212

213213
/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
214214
* AUX message. The sequence is slot 1-63 allocated sequence for each

drivers/gpu/drm/display/drm_dp_mst_topology.c

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3342,44 +3342,46 @@ EXPORT_SYMBOL(drm_dp_add_payload_part1);
33423342
* drm_dp_remove_payload() - Remove an MST payload
33433343
* @mgr: Manager to use.
33443344
* @mst_state: The MST atomic state
3345-
* @payload: The payload to write
3345+
* @old_payload: The payload with its old state
3346+
* @new_payload: The payload to write
33463347
*
33473348
* Removes a payload from an MST topology if it was successfully assigned a start slot. Also updates
33483349
* the starting time slots of all other payloads which would have been shifted towards the start of
33493350
* the VC table as a result. After calling this, the driver should generate ACT and payload packets.
33503351
*/
33513352
void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr,
33523353
struct drm_dp_mst_topology_state *mst_state,
3353-
struct drm_dp_mst_atomic_payload *payload)
3354+
const struct drm_dp_mst_atomic_payload *old_payload,
3355+
struct drm_dp_mst_atomic_payload *new_payload)
33543356
{
33553357
struct drm_dp_mst_atomic_payload *pos;
33563358
bool send_remove = false;
33573359

33583360
/* We failed to make the payload, so nothing to do */
3359-
if (payload->vc_start_slot == -1)
3361+
if (new_payload->vc_start_slot == -1)
33603362
return;
33613363

33623364
mutex_lock(&mgr->lock);
3363-
send_remove = drm_dp_mst_port_downstream_of_branch(payload->port, mgr->mst_primary);
3365+
send_remove = drm_dp_mst_port_downstream_of_branch(new_payload->port, mgr->mst_primary);
33643366
mutex_unlock(&mgr->lock);
33653367

33663368
if (send_remove)
3367-
drm_dp_destroy_payload_step1(mgr, mst_state, payload);
3369+
drm_dp_destroy_payload_step1(mgr, mst_state, new_payload);
33683370
else
33693371
drm_dbg_kms(mgr->dev, "Payload for VCPI %d not in topology, not sending remove\n",
3370-
payload->vcpi);
3372+
new_payload->vcpi);
33713373

33723374
list_for_each_entry(pos, &mst_state->payloads, next) {
3373-
if (pos != payload && pos->vc_start_slot > payload->vc_start_slot)
3374-
pos->vc_start_slot -= payload->time_slots;
3375+
if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)
3376+
pos->vc_start_slot -= old_payload->time_slots;
33753377
}
3376-
payload->vc_start_slot = -1;
3378+
new_payload->vc_start_slot = -1;
33773379

33783380
mgr->payload_count--;
3379-
mgr->next_start_slot -= payload->time_slots;
3381+
mgr->next_start_slot -= old_payload->time_slots;
33803382

3381-
if (payload->delete)
3382-
drm_dp_mst_put_port_malloc(payload->port);
3383+
if (new_payload->delete)
3384+
drm_dp_mst_put_port_malloc(new_payload->port);
33833385
}
33843386
EXPORT_SYMBOL(drm_dp_remove_payload);
33853387

@@ -5362,28 +5364,53 @@ struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_a
53625364
}
53635365
EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
53645366

5367+
/**
5368+
* drm_atomic_get_old_mst_topology_state: get old MST topology state in atomic state, if any
5369+
* @state: global atomic state
5370+
* @mgr: MST topology manager, also the private object in this case
5371+
*
5372+
* This function wraps drm_atomic_get_old_private_obj_state() passing in the MST atomic
5373+
* state vtable so that the private object state returned is that of a MST
5374+
* topology object.
5375+
*
5376+
* Returns:
5377+
*
5378+
* The old MST topology state, or NULL if there's no topology state for this MST mgr
5379+
* in the global atomic state
5380+
*/
5381+
struct drm_dp_mst_topology_state *
5382+
drm_atomic_get_old_mst_topology_state(struct drm_atomic_state *state,
5383+
struct drm_dp_mst_topology_mgr *mgr)
5384+
{
5385+
struct drm_private_state *old_priv_state =
5386+
drm_atomic_get_old_private_obj_state(state, &mgr->base);
5387+
5388+
return old_priv_state ? to_dp_mst_topology_state(old_priv_state) : NULL;
5389+
}
5390+
EXPORT_SYMBOL(drm_atomic_get_old_mst_topology_state);
5391+
53655392
/**
53665393
* drm_atomic_get_new_mst_topology_state: get new MST topology state in atomic state, if any
53675394
* @state: global atomic state
53685395
* @mgr: MST topology manager, also the private object in this case
53695396
*
5370-
* This function wraps drm_atomic_get_priv_obj_state() passing in the MST atomic
5397+
* This function wraps drm_atomic_get_new_private_obj_state() passing in the MST atomic
53715398
* state vtable so that the private object state returned is that of a MST
53725399
* topology object.
53735400
*
53745401
* Returns:
53755402
*
5376-
* The MST topology state, or NULL if there's no topology state for this MST mgr
5403+
* The new MST topology state, or NULL if there's no topology state for this MST mgr
53775404
* in the global atomic state
53785405
*/
53795406
struct drm_dp_mst_topology_state *
53805407
drm_atomic_get_new_mst_topology_state(struct drm_atomic_state *state,
53815408
struct drm_dp_mst_topology_mgr *mgr)
53825409
{
5383-
struct drm_private_state *priv_state =
5410+
struct drm_private_state *new_priv_state =
53845411
drm_atomic_get_new_private_obj_state(state, &mgr->base);
53855412

5386-
return priv_state ? to_dp_mst_topology_state(priv_state) : NULL;
5413+
return new_priv_state ? to_dp_mst_topology_state(new_priv_state) : NULL;
53875414
}
53885415
EXPORT_SYMBOL(drm_atomic_get_new_mst_topology_state);
53895416

drivers/gpu/drm/drm_panel_orientation_quirks.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,12 @@ static const struct dmi_system_id orientation_data[] = {
322322
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGL"),
323323
},
324324
.driver_data = (void *)&lcd800x1280_rightside_up,
325+
}, { /* Lenovo IdeaPad Duet 3 10IGL5 */
326+
.matches = {
327+
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
328+
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"),
329+
},
330+
.driver_data = (void *)&lcd1200x1920_rightside_up,
325331
}, { /* Lenovo Yoga Book X90F / X91F / X91L */
326332
.matches = {
327333
/* Non exact match to match all versions */

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5934,6 +5934,10 @@ int intel_modeset_all_pipes(struct intel_atomic_state *state,
59345934
if (ret)
59355935
return ret;
59365936

5937+
ret = intel_dp_mst_add_topology_state_for_crtc(state, crtc);
5938+
if (ret)
5939+
return ret;
5940+
59375941
ret = intel_atomic_add_affected_planes(state, crtc);
59385942
if (ret)
59395943
return ret;

drivers/gpu/drm/i915/display/intel_dp_mst.c

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -524,17 +524,23 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
524524
struct intel_dp *intel_dp = &dig_port->dp;
525525
struct intel_connector *connector =
526526
to_intel_connector(old_conn_state->connector);
527-
struct drm_dp_mst_topology_state *mst_state =
528-
drm_atomic_get_mst_topology_state(&state->base, &intel_dp->mst_mgr);
527+
struct drm_dp_mst_topology_state *old_mst_state =
528+
drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
529+
struct drm_dp_mst_topology_state *new_mst_state =
530+
drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
531+
const struct drm_dp_mst_atomic_payload *old_payload =
532+
drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
533+
struct drm_dp_mst_atomic_payload *new_payload =
534+
drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
529535
struct drm_i915_private *i915 = to_i915(connector->base.dev);
530536

531537
drm_dbg_kms(&i915->drm, "active links %d\n",
532538
intel_dp->active_mst_links);
533539

534540
intel_hdcp_disable(intel_mst->connector);
535541

536-
drm_dp_remove_payload(&intel_dp->mst_mgr, mst_state,
537-
drm_atomic_get_mst_payload_state(mst_state, connector->port));
542+
drm_dp_remove_payload(&intel_dp->mst_mgr, new_mst_state,
543+
old_payload, new_payload);
538544

539545
intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
540546
}
@@ -1223,3 +1229,64 @@ bool intel_dp_mst_is_slave_trans(const struct intel_crtc_state *crtc_state)
12231229
return crtc_state->mst_master_transcoder != INVALID_TRANSCODER &&
12241230
crtc_state->mst_master_transcoder != crtc_state->cpu_transcoder;
12251231
}
1232+
1233+
/**
1234+
* intel_dp_mst_add_topology_state_for_connector - add MST topology state for a connector
1235+
* @state: atomic state
1236+
* @connector: connector to add the state for
1237+
* @crtc: the CRTC @connector is attached to
1238+
*
1239+
* Add the MST topology state for @connector to @state.
1240+
*
1241+
* Returns 0 on success, negative error code on failure.
1242+
*/
1243+
static int
1244+
intel_dp_mst_add_topology_state_for_connector(struct intel_atomic_state *state,
1245+
struct intel_connector *connector,
1246+
struct intel_crtc *crtc)
1247+
{
1248+
struct drm_dp_mst_topology_state *mst_state;
1249+
1250+
if (!connector->mst_port)
1251+
return 0;
1252+
1253+
mst_state = drm_atomic_get_mst_topology_state(&state->base,
1254+
&connector->mst_port->mst_mgr);
1255+
if (IS_ERR(mst_state))
1256+
return PTR_ERR(mst_state);
1257+
1258+
mst_state->pending_crtc_mask |= drm_crtc_mask(&crtc->base);
1259+
1260+
return 0;
1261+
}
1262+
1263+
/**
1264+
* intel_dp_mst_add_topology_state_for_crtc - add MST topology state for a CRTC
1265+
* @state: atomic state
1266+
* @crtc: CRTC to add the state for
1267+
*
1268+
* Add the MST topology state for @crtc to @state.
1269+
*
1270+
* Returns 0 on success, negative error code on failure.
1271+
*/
1272+
int intel_dp_mst_add_topology_state_for_crtc(struct intel_atomic_state *state,
1273+
struct intel_crtc *crtc)
1274+
{
1275+
struct drm_connector *_connector;
1276+
struct drm_connector_state *conn_state;
1277+
int i;
1278+
1279+
for_each_new_connector_in_state(&state->base, _connector, conn_state, i) {
1280+
struct intel_connector *connector = to_intel_connector(_connector);
1281+
int ret;
1282+
1283+
if (conn_state->crtc != &crtc->base)
1284+
continue;
1285+
1286+
ret = intel_dp_mst_add_topology_state_for_connector(state, connector, crtc);
1287+
if (ret)
1288+
return ret;
1289+
}
1290+
1291+
return 0;
1292+
}

drivers/gpu/drm/i915/display/intel_dp_mst.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include <linux/types.h>
1010

11+
struct intel_atomic_state;
12+
struct intel_crtc;
1113
struct intel_crtc_state;
1214
struct intel_digital_port;
1315
struct intel_dp;
@@ -18,5 +20,7 @@ int intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port);
1820
bool intel_dp_mst_is_master_trans(const struct intel_crtc_state *crtc_state);
1921
bool intel_dp_mst_is_slave_trans(const struct intel_crtc_state *crtc_state);
2022
bool intel_dp_mst_source_support(struct intel_dp *intel_dp);
23+
int intel_dp_mst_add_topology_state_for_crtc(struct intel_atomic_state *state,
24+
struct intel_crtc *crtc);
2125

2226
#endif /* __INTEL_DP_MST_H__ */

drivers/gpu/drm/nouveau/dispnv50/disp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ nv50_msto_prepare(struct drm_atomic_state *state,
885885

886886
// TODO: Figure out if we want to do a better job of handling VCPI allocation failures here?
887887
if (msto->disabled) {
888-
drm_dp_remove_payload(mgr, mst_state, payload);
888+
drm_dp_remove_payload(mgr, mst_state, payload, payload);
889889

890890
nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index, 0, 0, 0, 0);
891891
} else {

include/drm/display/drm_dp_mst_helper.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,8 @@ int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
841841
struct drm_dp_mst_atomic_payload *payload);
842842
void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr,
843843
struct drm_dp_mst_topology_state *mst_state,
844-
struct drm_dp_mst_atomic_payload *payload);
844+
const struct drm_dp_mst_atomic_payload *old_payload,
845+
struct drm_dp_mst_atomic_payload *new_payload);
845846

846847
int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
847848

@@ -867,6 +868,9 @@ struct drm_dp_mst_topology_state *
867868
drm_atomic_get_mst_topology_state(struct drm_atomic_state *state,
868869
struct drm_dp_mst_topology_mgr *mgr);
869870
struct drm_dp_mst_topology_state *
871+
drm_atomic_get_old_mst_topology_state(struct drm_atomic_state *state,
872+
struct drm_dp_mst_topology_mgr *mgr);
873+
struct drm_dp_mst_topology_state *
870874
drm_atomic_get_new_mst_topology_state(struct drm_atomic_state *state,
871875
struct drm_dp_mst_topology_mgr *mgr);
872876
struct drm_dp_mst_atomic_payload *

0 commit comments

Comments
 (0)