Message ID | 20180615195221.18119-1-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 2018-06-15 03:52 PM, Ville Syrjala wrote: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > To pick the correct MST encoder i915 wants to know which crtc is going > to be feeding us. To that end let's pass the crtc to the .best_encoder() > hook. The atomic variant already knows the crtc via the connector state, > but the non-atomic hooks is still being used by the fb_helper even on > atomic drivers. > > This allows us to fix up the possible_crtcs bitmask for the i915 MST > encoders. We have one encoder for each crtc+port combination, and thus > we have to know both the connector and the crtc to pick the right one. > This has only worked so far because every MST encoder lied in its > possible_crtcs bitmask that they can be driven by any crtc. > > I took the easy way out and passed NULL as the crtc for all the driver > internal uses of .best_encoder() in the amdgpu/radeon drivers. None of > the other drivers have such internal uses. The other callers > (crtc_helper, atomic_helper, fb_helper) will pass in the proper crtc. > but no one besides i915 will currently look at it. > > Cc: Alex Deucher <alexander.deucher@amd.com> > Cc: "Christian König" <christian.koenig@amd.com> > Cc: "David (ChunMing) Zhou" <David1.Zhou@amd.com> > Cc: Harry Wentland <harry.wentland@amd.com> > Cc: amd-gfx@lists.freedesktop.org > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> amdgpu parts are Acked-by: Harry Wentland <harry.wentland@amd.com> Harry > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 33 +++++++++-------- > drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 3 +- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++-- > .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 5 +-- > drivers/gpu/drm/ast/ast_mode.c | 3 +- > drivers/gpu/drm/bochs/bochs_kms.c | 3 +- > drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 3 +- > drivers/gpu/drm/bridge/tc358767.c | 3 +- > drivers/gpu/drm/cirrus/cirrus_mode.c | 5 +-- > drivers/gpu/drm/drm_atomic_helper.c | 16 ++++++--- > drivers/gpu/drm/drm_crtc_helper.c | 3 +- > drivers/gpu/drm/drm_fb_helper.c | 41 ++++++++++++---------- > drivers/gpu/drm/gma500/gma_display.c | 3 +- > drivers/gpu/drm/gma500/mdfld_dsi_output.c | 5 +-- > drivers/gpu/drm/gma500/psb_intel_drv.h | 3 +- > drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 3 +- > drivers/gpu/drm/i2c/tda998x_drv.c | 3 +- > drivers/gpu/drm/i915/intel_dp_mst.c | 9 +++-- > drivers/gpu/drm/imx/imx-ldb.c | 5 +-- > drivers/gpu/drm/imx/imx-tve.c | 5 +-- > drivers/gpu/drm/imx/parallel-display.c | 5 +-- > drivers/gpu/drm/mediatek/mtk_hdmi.c | 3 +- > drivers/gpu/drm/mgag200/mgag200_mode.c | 5 +-- > drivers/gpu/drm/msm/dsi/dsi_manager.c | 3 +- > drivers/gpu/drm/nouveau/dispnv50/disp.c | 3 +- > drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +- > drivers/gpu/drm/qxl/qxl_display.c | 3 +- > drivers/gpu/drm/radeon/radeon_connectors.c | 40 +++++++++++---------- > drivers/gpu/drm/radeon/radeon_dp_mst.c | 5 +-- > drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 3 +- > drivers/gpu/drm/tilcdc/tilcdc_panel.c | 5 +-- > drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 5 +-- > drivers/gpu/drm/udl/udl_connector.c | 3 +- > drivers/staging/vboxvideo/vbox_mode.c | 5 +-- > include/drm/drm_atomic_helper.h | 3 +- > include/drm/drm_modeset_helper_vtables.h | 6 ++-- > 36 files changed, 155 insertions(+), 106 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > index 8e66851eb427..3dfa50ec2589 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > @@ -135,7 +135,8 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) > else { > const struct drm_connector_helper_funcs *connector_funcs = > connector->helper_private; > - struct drm_encoder *encoder = connector_funcs->best_encoder(connector); > + struct drm_encoder *encoder = connector_funcs->best_encoder(connector, > + NULL); > struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder); > struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv; > > @@ -218,7 +219,7 @@ amdgpu_connector_update_scratch_regs(struct drm_connector *connector, > bool connected; > int i; > > - best_encoder = connector_funcs->best_encoder(connector); > + best_encoder = connector_funcs->best_encoder(connector, NULL); > > for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { > if (connector->encoder_ids[i] == 0) > @@ -358,7 +359,8 @@ static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) > } > > static struct drm_encoder * > -amdgpu_connector_best_single_encoder(struct drm_connector *connector) > +amdgpu_connector_best_single_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > > @@ -370,7 +372,7 @@ amdgpu_connector_best_single_encoder(struct drm_connector *connector) > > static void amdgpu_get_native_mode(struct drm_connector *connector) > { > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > struct amdgpu_encoder *amdgpu_encoder; > > if (encoder == NULL) > @@ -593,7 +595,7 @@ static int amdgpu_connector_set_property(struct drm_connector *connector, > amdgpu_encoder = to_amdgpu_encoder(connector->encoder); > } else { > const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; > - amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector)); > + amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector, NULL)); > } > > switch (val) { > @@ -663,7 +665,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) > amdgpu_connector_get_edid(connector); > ret = amdgpu_connector_ddc_get_modes(connector); > if (ret > 0) { > - encoder = amdgpu_connector_best_single_encoder(connector); > + encoder = amdgpu_connector_best_single_encoder(connector, NULL); > if (encoder) { > amdgpu_connector_fixup_lcd_native_mode(encoder, connector); > /* add scaled modes */ > @@ -672,7 +674,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) > return ret; > } > > - encoder = amdgpu_connector_best_single_encoder(connector); > + encoder = amdgpu_connector_best_single_encoder(connector, NULL); > if (!encoder) > return 0; > > @@ -694,7 +696,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) > static enum drm_mode_status amdgpu_connector_lvds_mode_valid(struct drm_connector *connector, > struct drm_display_mode *mode) > { > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > > if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) > return MODE_PANEL; > @@ -725,7 +727,7 @@ static enum drm_connector_status > amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force) > { > struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > enum drm_connector_status ret = connector_status_disconnected; > int r; > > @@ -798,7 +800,7 @@ static int amdgpu_connector_set_lcd_property(struct drm_connector *connector, > amdgpu_encoder = to_amdgpu_encoder(connector->encoder); > else { > const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; > - amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector)); > + amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector, NULL)); > } > > switch (value) { > @@ -873,7 +875,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) > return connector_status_disconnected; > } > > - encoder = amdgpu_connector_best_single_encoder(connector); > + encoder = amdgpu_connector_best_single_encoder(connector, NULL); > if (!encoder) > ret = connector_status_disconnected; > > @@ -1130,7 +1132,8 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) > > /* okay need to be smart in here about which encoder to pick */ > static struct drm_encoder * > -amdgpu_connector_dvi_encoder(struct drm_connector *connector) > +amdgpu_connector_dvi_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); > @@ -1224,7 +1227,7 @@ static int amdgpu_connector_dp_get_modes(struct drm_connector *connector) > { > struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); > struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv; > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > int ret; > > if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || > @@ -1363,7 +1366,7 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) > struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); > enum drm_connector_status ret = connector_status_disconnected; > struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv; > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > int r; > > if (!drm_kms_helper_is_poll_worker()) { > @@ -1458,7 +1461,7 @@ static enum drm_mode_status amdgpu_connector_dp_mode_valid(struct drm_connector > > if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || > (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > > if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) > return MODE_PANEL; > diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c > index dbf2ccd0c744..b02ce39e65b7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c > +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c > @@ -267,7 +267,8 @@ static int dce_virtual_early_init(void *handle) > } > > static struct drm_encoder * > -dce_virtual_encoder(struct drm_connector *connector) > +dce_virtual_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > struct drm_encoder *encoder; > 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 3e1c2a04d669..e56ed4e5818f 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -2758,7 +2758,8 @@ static const struct drm_connector_funcs amdgpu_dm_connector_funcs = { > .atomic_get_property = amdgpu_dm_connector_atomic_get_property > }; > > -static struct drm_encoder *best_encoder(struct drm_connector *connector) > +static struct drm_encoder *best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > struct drm_mode_object *obj; > @@ -3304,7 +3305,7 @@ static void amdgpu_dm_get_native_mode(struct drm_connector *connector) > struct drm_encoder *encoder; > struct amdgpu_encoder *amdgpu_encoder; > > - encoder = helper->best_encoder(connector); > + encoder = helper->best_encoder(connector, NULL); > > if (encoder == NULL) > return; > @@ -3438,7 +3439,7 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) > struct drm_encoder *encoder; > struct edid *edid = amdgpu_dm_connector->edid; > > - encoder = helper->best_encoder(connector); > + encoder = helper->best_encoder(connector, NULL); > amdgpu_dm_connector_ddc_get_modes(connector, edid); > amdgpu_dm_connector_add_common_modes(encoder, connector); > > 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 4304d9e408b8..4544a1401caf 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 > @@ -269,7 +269,8 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) > return ret; > } > > -static struct drm_encoder *dm_mst_best_encoder(struct drm_connector *connector) > +static struct drm_encoder *dm_mst_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); > > @@ -302,7 +303,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector) > const struct drm_connector_helper_funcs *connector_funcs = > connector->base.helper_private; > struct drm_encoder *enc_master = > - connector_funcs->best_encoder(&connector->base); > + connector_funcs->best_encoder(&connector->base, NULL); > > DRM_DEBUG_KMS("enc master is %p\n", enc_master); > amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL); > diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c > index 036dff8a1f33..d5899aa41d37 100644 > --- a/drivers/gpu/drm/ast/ast_mode.c > +++ b/drivers/gpu/drm/ast/ast_mode.c > @@ -709,7 +709,8 @@ static void ast_encoder_destroy(struct drm_encoder *encoder) > } > > > -static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connector) > +static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > /* pick the encoder ids */ > diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c > index 233980a78591..dc80a238feef 100644 > --- a/drivers/gpu/drm/bochs/bochs_kms.c > +++ b/drivers/gpu/drm/bochs/bochs_kms.c > @@ -208,7 +208,8 @@ static enum drm_mode_status bochs_connector_mode_valid(struct drm_connector *con > } > > static struct drm_encoder * > -bochs_connector_best_encoder(struct drm_connector *connector) > +bochs_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > /* pick the encoder ids */ > diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > index 2bcbfadb6ac5..0706471c8c63 100644 > --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > @@ -1137,7 +1137,8 @@ static int analogix_dp_get_modes(struct drm_connector *connector) > } > > static struct drm_encoder * > -analogix_dp_best_encoder(struct drm_connector *connector) > +analogix_dp_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct analogix_dp_device *dp = to_dp(connector); > > diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c > index 0fd9cf27542c..7cd954226fe3 100644 > --- a/drivers/gpu/drm/bridge/tc358767.c > +++ b/drivers/gpu/drm/bridge/tc358767.c > @@ -1155,7 +1155,8 @@ static void tc_connector_set_polling(struct tc_data *tc, > } > > static struct drm_encoder * > -tc_connector_best_encoder(struct drm_connector *connector) > +tc_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct tc_data *tc = connector_to_tc(connector); > > diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c > index b529f8c8e2a6..378ebc3f25e8 100644 > --- a/drivers/gpu/drm/cirrus/cirrus_mode.c > +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c > @@ -451,8 +451,9 @@ static int cirrus_vga_get_modes(struct drm_connector *connector) > return count; > } > > -static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector > - *connector) > +static struct drm_encoder * > +cirrus_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > /* pick the encoder ids */ > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c > index 232fa11a5e31..bd3aebbfd5b4 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -115,9 +115,11 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, > if (funcs->atomic_best_encoder) > new_encoder = funcs->atomic_best_encoder(connector, new_conn_state); > else if (funcs->best_encoder) > - new_encoder = funcs->best_encoder(connector); > + new_encoder = funcs->best_encoder(connector, > + new_conn_state->crtc); > else > - new_encoder = drm_atomic_helper_best_encoder(connector); > + new_encoder = drm_atomic_helper_best_encoder(connector, > + new_conn_state->crtc); > > if (new_encoder) { > if (encoder_mask & (1 << drm_encoder_index(new_encoder))) { > @@ -312,9 +314,11 @@ update_connector_routing(struct drm_atomic_state *state, > new_encoder = funcs->atomic_best_encoder(connector, > new_connector_state); > else if (funcs->best_encoder) > - new_encoder = funcs->best_encoder(connector); > + new_encoder = funcs->best_encoder(connector, > + new_connector_state->crtc); > else > - new_encoder = drm_atomic_helper_best_encoder(connector); > + new_encoder = drm_atomic_helper_best_encoder(connector, > + new_connector_state->crtc); > > if (!new_encoder) { > DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n", > @@ -3318,13 +3322,15 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip_target); > * drm_atomic_helper_best_encoder - Helper for > * &drm_connector_helper_funcs.best_encoder callback > * @connector: Connector control structure > + * @crtc: DRM crtc > * > * This is a &drm_connector_helper_funcs.best_encoder callback helper for > * connectors that support exactly 1 encoder, statically determined at driver > * init time. > */ > struct drm_encoder * > -drm_atomic_helper_best_encoder(struct drm_connector *connector) > +drm_atomic_helper_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > WARN_ON(connector->encoder_ids[1]); > return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); > diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c > index 5a84c3bc915d..f9318fc11fb1 100644 > --- a/drivers/gpu/drm/drm_crtc_helper.c > +++ b/drivers/gpu/drm/drm_crtc_helper.c > @@ -637,7 +637,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set, > new_encoder = connector->encoder; > for (ro = 0; ro < set->num_connectors; ro++) { > if (set->connectors[ro] == connector) { > - new_encoder = connector_funcs->best_encoder(connector); > + new_encoder = connector_funcs->best_encoder(connector, > + set->crtc); > /* if we can't get an encoder for a connector > we are setting now - then fail */ > if (new_encoder == NULL) > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c > index cab14f253384..ce91ae12cccb 100644 > --- a/drivers/gpu/drm/drm_fb_helper.c > +++ b/drivers/gpu/drm/drm_fb_helper.c > @@ -2331,9 +2331,8 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, > int c, o; > struct drm_connector *connector; > const struct drm_connector_helper_funcs *connector_funcs; > - struct drm_encoder *encoder; > int my_score, best_score, score; > - struct drm_fb_helper_crtc **crtcs, *crtc; > + struct drm_fb_helper_crtc **crtcs; > struct drm_fb_helper_connector *fb_helper_conn; > > if (n == fb_helper->connector_count) > @@ -2362,28 +2361,32 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, > > connector_funcs = connector->helper_private; > > - /* > - * If the DRM device implements atomic hooks and ->best_encoder() is > - * NULL we fallback to the default drm_atomic_helper_best_encoder() > - * helper. > - */ > - if (drm_drv_uses_atomic_modeset(fb_helper->dev) && > - !connector_funcs->best_encoder) > - encoder = drm_atomic_helper_best_encoder(connector); > - else > - encoder = connector_funcs->best_encoder(connector); > - > - if (!encoder) > - goto out; > - > /* > * select a crtc for this connector and then attempt to configure > * remaining connectors > */ > for (c = 0; c < fb_helper->crtc_count; c++) { > - crtc = &fb_helper->crtc_info[c]; > + struct drm_encoder *encoder; > + struct drm_fb_helper_crtc *crtc = &fb_helper->crtc_info[c]; > > - if ((encoder->possible_crtcs & (1 << c)) == 0) > + /* > + * If the DRM device implements atomic hooks and ->best_encoder() is > + * NULL we fallback to the default drm_atomic_helper_best_encoder() > + * helper. > + */ > + if (drm_drv_uses_atomic_modeset(fb_helper->dev) && > + !connector_funcs->best_encoder) > + encoder = drm_atomic_helper_best_encoder(connector, > + crtc->mode_set.crtc); > + else > + encoder = connector_funcs->best_encoder(connector, > + crtc->mode_set.crtc); > + > + if (!encoder) > + continue; > + > + if ((encoder->possible_crtcs & > + drm_crtc_mask(crtc->mode_set.crtc)) == 0) > continue; > > for (o = 0; o < n; o++) > @@ -2410,7 +2413,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, > sizeof(struct drm_fb_helper_crtc *)); > } > } > -out: > + > kfree(crtcs); > return best_score; > } > diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c > index c8f071c47daf..251b64653dc8 100644 > --- a/drivers/gpu/drm/gma500/gma_display.c > +++ b/drivers/gpu/drm/gma500/gma_display.c > @@ -652,7 +652,8 @@ void gma_encoder_destroy(struct drm_encoder *encoder) > } > > /* Currently there is only a 1:1 mapping of encoders and connectors */ > -struct drm_encoder *gma_best_encoder(struct drm_connector *connector) > +struct drm_encoder *gma_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct gma_encoder *gma_encoder = gma_attached_encoder(connector); > > diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c > index fe020926ea4f..9e5b059a9e5b 100644 > --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c > +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c > @@ -377,8 +377,9 @@ static enum drm_mode_status mdfld_dsi_connector_mode_valid(struct drm_connector > return MODE_OK; > } > > -static struct drm_encoder *mdfld_dsi_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +mdfld_dsi_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct mdfld_dsi_connector *dsi_connector = > mdfld_dsi_connector(connector); > diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h > index e05e5399af2d..e903525b9d30 100644 > --- a/drivers/gpu/drm/gma500/psb_intel_drv.h > +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h > @@ -230,7 +230,8 @@ extern void oaktrail_lvds_i2c_init(struct drm_encoder *encoder); > extern void mid_dsi_init(struct drm_device *dev, > struct psb_intel_mode_device *mode_dev, int dsi_num); > > -extern struct drm_encoder *gma_best_encoder(struct drm_connector *connector); > +extern struct drm_encoder *gma_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc); > extern void gma_connector_attach_encoder(struct gma_connector *connector, > struct gma_encoder *encoder); > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c > index d2f4749ebf8d..89a0104f9855 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c > +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c > @@ -34,7 +34,8 @@ static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *con > } > > static struct drm_encoder * > -hibmc_connector_best_encoder(struct drm_connector *connector) > +hibmc_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); > } > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index 0038c976536a..422347d977b4 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -1267,7 +1267,8 @@ static enum drm_mode_status tda998x_connector_mode_valid(struct drm_connector *c > } > > static struct drm_encoder * > -tda998x_connector_best_encoder(struct drm_connector *connector) > +tda998x_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct tda998x_priv *priv = conn_to_tda998x_priv(connector); > > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c > index 5890500a3a8b..d9119d516579 100644 > --- a/drivers/gpu/drm/i915/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c > @@ -403,20 +403,23 @@ static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *c > return &intel_dp->mst_encoders[crtc->pipe]->base.base; > } > > -static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector) > +static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector, > + struct drm_crtc *_crtc) > { > struct intel_connector *intel_connector = to_intel_connector(connector); > struct intel_dp *intel_dp = intel_connector->mst_port; > + struct intel_crtc *crtc = to_intel_crtc(_crtc); > + > if (!intel_dp) > return NULL; > - return &intel_dp->mst_encoders[0]->base.base; > + return &intel_dp->mst_encoders[crtc->pipe]->base.base; > } > > static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { > .get_modes = intel_dp_mst_get_modes, > .mode_valid = intel_dp_mst_mode_valid, > .atomic_best_encoder = intel_mst_atomic_best_encoder, > - .best_encoder = intel_mst_best_encoder, > + .best_encoder = intel_mst_best_encoder, /* only for fb_helper */ > .atomic_check = intel_dp_mst_atomic_check, > }; > > diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c > index 56dd7a9a8e25..f1523cccc090 100644 > --- a/drivers/gpu/drm/imx/imx-ldb.c > +++ b/drivers/gpu/drm/imx/imx-ldb.c > @@ -163,8 +163,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) > return num_modes; > } > > -static struct drm_encoder *imx_ldb_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +imx_ldb_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); > > diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c > index bc27c2699464..71f49ac835ec 100644 > --- a/drivers/gpu/drm/imx/imx-tve.c > +++ b/drivers/gpu/drm/imx/imx-tve.c > @@ -265,8 +265,9 @@ static int imx_tve_connector_mode_valid(struct drm_connector *connector, > return MODE_BAD; > } > > -static struct drm_encoder *imx_tve_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +imx_tve_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct imx_tve *tve = con_to_tve(connector); > > diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c > index aedecda9728a..438f95dee73e 100644 > --- a/drivers/gpu/drm/imx/parallel-display.c > +++ b/drivers/gpu/drm/imx/parallel-display.c > @@ -89,8 +89,9 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) > return num_modes; > } > > -static struct drm_encoder *imx_pd_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +imx_pd_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct imx_parallel_display *imxpd = con_to_imxpd(connector); > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c > index 59a11026dceb..c0578779fb19 100644 > --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c > @@ -1253,7 +1253,8 @@ static int mtk_hdmi_conn_mode_valid(struct drm_connector *conn, > return drm_mode_validate_size(mode, 0x1fff, 0x1fff); > } > > -static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn) > +static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn, > + struct drm_crtc *crtc) > { > struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); > > diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c > index 8918539a19aa..4059f04030ee 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_mode.c > +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c > @@ -1664,8 +1664,9 @@ static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector, > return MODE_OK; > } > > -static struct drm_encoder *mga_connector_best_encoder(struct drm_connector > - *connector) > +static struct drm_encoder * > +mga_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > /* pick the encoder ids */ > diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c > index 4cb1cb68878b..8cbede64819e 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c > @@ -426,7 +426,8 @@ static int dsi_mgr_connector_mode_valid(struct drm_connector *connector, > } > > static struct drm_encoder * > -dsi_mgr_connector_best_encoder(struct drm_connector *connector) > +dsi_mgr_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int id = dsi_mgr_connector_get_id(connector); > struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); > diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c > index b83465ae7c1b..a9bacb0a1e16 100644 > --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c > +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c > @@ -826,7 +826,8 @@ nv50_mstc_atomic_best_encoder(struct drm_connector *connector, > } > > static struct drm_encoder * > -nv50_mstc_best_encoder(struct drm_connector *connector) > +nv50_mstc_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct nv50_mstc *mstc = nv50_mstc(connector); > if (mstc->port) { > diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c > index 7b557c354307..ee4bf532b932 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_connector.c > +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c > @@ -1063,7 +1063,8 @@ nouveau_connector_mode_valid(struct drm_connector *connector, > } > > static struct drm_encoder * > -nouveau_connector_best_encoder(struct drm_connector *connector) > +nouveau_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct nouveau_connector *nv_connector = nouveau_connector(connector); > > diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c > index 768207fbbae3..fa5c84f35531 100644 > --- a/drivers/gpu/drm/qxl/qxl_display.c > +++ b/drivers/gpu/drm/qxl/qxl_display.c > @@ -978,7 +978,8 @@ static enum drm_mode_status qxl_conn_mode_valid(struct drm_connector *connector, > return MODE_BAD; > } > > -static struct drm_encoder *qxl_best_encoder(struct drm_connector *connector) > +static struct drm_encoder *qxl_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct qxl_output *qxl_output = > drm_connector_to_qxl_output(connector); > diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c > index 2aea2bdff99b..8bf7298dccb3 100644 > --- a/drivers/gpu/drm/radeon/radeon_connectors.c > +++ b/drivers/gpu/drm/radeon/radeon_connectors.c > @@ -158,7 +158,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) > else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { > const struct drm_connector_helper_funcs *connector_funcs = > connector->helper_private; > - struct drm_encoder *encoder = connector_funcs->best_encoder(connector); > + struct drm_encoder *encoder = connector_funcs->best_encoder(connector, NULL); > struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); > struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; > > @@ -250,7 +250,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c > bool connected; > int i; > > - best_encoder = connector_funcs->best_encoder(connector); > + best_encoder = connector_funcs->best_encoder(connector, NULL); > > for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { > if (connector->encoder_ids[i] == 0) > @@ -391,7 +391,8 @@ static int radeon_ddc_get_modes(struct drm_connector *connector) > return 0; > } > > -static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) > +static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > /* pick the encoder ids */ > @@ -402,7 +403,7 @@ static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *conn > > static void radeon_get_native_mode(struct drm_connector *connector) > { > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > struct radeon_encoder *radeon_encoder; > > if (encoder == NULL) > @@ -728,7 +729,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct > radeon_encoder = to_radeon_encoder(connector->encoder); > else { > const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; > - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); > + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); > } > > switch (val) { > @@ -755,7 +756,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct > radeon_encoder = to_radeon_encoder(connector->encoder); > else { > const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; > - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); > + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); > } > > if (radeon_encoder->output_csc == val) > @@ -824,7 +825,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) > radeon_connector_get_edid(connector); > ret = radeon_ddc_get_modes(connector); > if (ret > 0) { > - encoder = radeon_best_single_encoder(connector); > + encoder = radeon_best_single_encoder(connector, NULL); > if (encoder) { > radeon_fixup_lvds_native_mode(encoder, connector); > /* add scaled modes */ > @@ -833,7 +834,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) > return ret; > } > > - encoder = radeon_best_single_encoder(connector); > + encoder = radeon_best_single_encoder(connector, NULL); > if (!encoder) > return 0; > > @@ -855,7 +856,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) > static enum drm_mode_status radeon_lvds_mode_valid(struct drm_connector *connector, > struct drm_display_mode *mode) > { > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > > if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) > return MODE_PANEL; > @@ -888,7 +889,7 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) > struct drm_device *dev = connector->dev; > struct radeon_device *rdev = dev->dev_private; > struct radeon_connector *radeon_connector = to_radeon_connector(connector); > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > enum drm_connector_status ret = connector_status_disconnected; > int r; > > @@ -965,7 +966,7 @@ static int radeon_lvds_set_property(struct drm_connector *connector, > radeon_encoder = to_radeon_encoder(connector->encoder); > else { > const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; > - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); > + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); > } > > switch (value) { > @@ -1044,7 +1045,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) > return connector_status_disconnected; > } > > - encoder = radeon_best_single_encoder(connector); > + encoder = radeon_best_single_encoder(connector, NULL); > if (!encoder) > ret = connector_status_disconnected; > > @@ -1139,7 +1140,7 @@ static int radeon_tv_get_modes(struct drm_connector *connector) > struct drm_display_mode *tv_mode; > struct drm_encoder *encoder; > > - encoder = radeon_best_single_encoder(connector); > + encoder = radeon_best_single_encoder(connector, NULL); > if (!encoder) > return 0; > > @@ -1182,7 +1183,7 @@ radeon_tv_detect(struct drm_connector *connector, bool force) > return connector_status_disconnected; > } > > - encoder = radeon_best_single_encoder(connector); > + encoder = radeon_best_single_encoder(connector, NULL); > if (!encoder) > ret = connector_status_disconnected; > else { > @@ -1439,7 +1440,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) > const struct drm_connector_helper_funcs *connector_funcs = > connector->helper_private; > > - encoder = connector_funcs->best_encoder(connector); > + encoder = connector_funcs->best_encoder(connector, NULL); > if (encoder && (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)) { > radeon_connector_get_edid(connector); > radeon_audio_detect(connector, encoder, ret); > @@ -1456,7 +1457,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) > } > > /* okay need to be smart in here about which encoder to pick */ > -static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) > +static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > struct radeon_connector *radeon_connector = to_radeon_connector(connector); > @@ -1556,7 +1558,7 @@ static int radeon_dp_get_modes(struct drm_connector *connector) > { > struct radeon_connector *radeon_connector = to_radeon_connector(connector); > struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > int ret; > > if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || > @@ -1695,7 +1697,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) > struct radeon_connector *radeon_connector = to_radeon_connector(connector); > enum drm_connector_status ret = connector_status_disconnected; > struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > int r; > > if (radeon_dig_connector->is_mst) > @@ -1812,7 +1814,7 @@ static enum drm_mode_status radeon_dp_mode_valid(struct drm_connector *connector > > if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || > (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > > if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) > return MODE_PANEL; > diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c > index cd8a3ee16649..fd5a0dae0e1f 100644 > --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c > +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c > @@ -224,7 +224,8 @@ radeon_dp_mst_mode_valid(struct drm_connector *connector, > } > > static struct > -drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector) > +drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct radeon_connector *radeon_connector = to_radeon_connector(connector); > > @@ -613,7 +614,7 @@ radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector) > struct radeon_encoder_mst *mst_enc; > struct drm_encoder *encoder; > const struct drm_connector_helper_funcs *connector_funcs = connector->base.helper_private; > - struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base); > + struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base, NULL); > > DRM_DEBUG_KMS("enc master is %p\n", enc_master); > radeon_encoder = kzalloc(sizeof(*radeon_encoder), GFP_KERNEL); > diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c > index e7738939a86d..cdc991d5c28e 100644 > --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c > @@ -668,7 +668,8 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector) > } > > static struct drm_encoder * > -shmob_drm_connector_best_encoder(struct drm_connector *connector) > +shmob_drm_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct shmob_drm_connector *scon = to_shmob_connector(connector); > > diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c > index d616d64a6725..197962eca1af 100644 > --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c > +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c > @@ -178,8 +178,9 @@ static int panel_connector_mode_valid(struct drm_connector *connector, > return tilcdc_crtc_mode_valid(priv->crtc, mode); > } > > -static struct drm_encoder *panel_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +panel_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct panel_connector *panel_connector = to_panel_connector(connector); > return panel_connector->encoder; > diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c > index c45cabb38db0..0ef8221c5334 100644 > --- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c > +++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c > @@ -191,8 +191,9 @@ static int tfp410_connector_mode_valid(struct drm_connector *connector, > return tilcdc_crtc_mode_valid(priv->crtc, mode); > } > > -static struct drm_encoder *tfp410_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +tfp410_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector); > return tfp410_connector->encoder; > diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c > index 09dc585aa46f..803ae6515892 100644 > --- a/drivers/gpu/drm/udl/udl_connector.c > +++ b/drivers/gpu/drm/udl/udl_connector.c > @@ -145,7 +145,8 @@ udl_detect(struct drm_connector *connector, bool force) > } > > static struct drm_encoder* > -udl_best_single_encoder(struct drm_connector *connector) > +udl_best_single_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > return drm_encoder_find(connector->dev, NULL, enc_id); > diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c > index b265fe924556..bf0e93705e1c 100644 > --- a/drivers/staging/vboxvideo/vbox_mode.c > +++ b/drivers/staging/vboxvideo/vbox_mode.c > @@ -370,8 +370,9 @@ static void vbox_encoder_destroy(struct drm_encoder *encoder) > kfree(encoder); > } > > -static struct drm_encoder *vbox_best_single_encoder(struct drm_connector > - *connector) > +static struct drm_encoder * > +vbox_best_single_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > > diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h > index 26aaba58d6ce..e0f00d43ed63 100644 > --- a/include/drm/drm_atomic_helper.h > +++ b/include/drm/drm_atomic_helper.h > @@ -143,7 +143,8 @@ int drm_atomic_helper_page_flip_target( > uint32_t target, > struct drm_modeset_acquire_ctx *ctx); > struct drm_encoder * > -drm_atomic_helper_best_encoder(struct drm_connector *connector); > +drm_atomic_helper_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc); > > /* default implementations for state handling */ > void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h > index 35e2a3a79fc5..a9b3a2c50877 100644 > --- a/include/drm/drm_modeset_helper_vtables.h > +++ b/include/drm/drm_modeset_helper_vtables.h > @@ -885,7 +885,8 @@ struct drm_connector_helper_funcs { > /** > * @best_encoder: > * > - * This function should select the best encoder for the given connector. > + * This function should select the best encoder for the given connector > + * and crtc. For some driver internal use crtc may be NULL. > * > * This function is used by both the atomic helpers (in the > * drm_atomic_helper_check_modeset() function) and in the legacy CRTC > @@ -911,7 +912,8 @@ struct drm_connector_helper_funcs { > * will ensure that encoders aren't used twice, drivers should not check > * for this. > */ > - struct drm_encoder *(*best_encoder)(struct drm_connector *connector); > + struct drm_encoder *(*best_encoder)(struct drm_connector *connector, > + struct drm_crtc *crtc); > > /** > * @atomic_best_encoder: >
On Fri, Jun 15, 2018 at 10:52:21PM +0300, Ville Syrjala wrote: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > To pick the correct MST encoder i915 wants to know which crtc is going > to be feeding us. To that end let's pass the crtc to the .best_encoder() > hook. The atomic variant already knows the crtc via the connector state, > but the non-atomic hooks is still being used by the fb_helper even on > atomic drivers. Can't we instead fix the fb helpers to use atomic_best_encoder? Or just drop that code, userspace doesn't really know any better either and just needs to figure this out without the help of ->best_encoder, so it should be possible. -Daniel > > This allows us to fix up the possible_crtcs bitmask for the i915 MST > encoders. We have one encoder for each crtc+port combination, and thus > we have to know both the connector and the crtc to pick the right one. > This has only worked so far because every MST encoder lied in its > possible_crtcs bitmask that they can be driven by any crtc. > > I took the easy way out and passed NULL as the crtc for all the driver > internal uses of .best_encoder() in the amdgpu/radeon drivers. None of > the other drivers have such internal uses. The other callers > (crtc_helper, atomic_helper, fb_helper) will pass in the proper crtc. > but no one besides i915 will currently look at it. > > Cc: Alex Deucher <alexander.deucher@amd.com> > Cc: "Christian König" <christian.koenig@amd.com> > Cc: "David (ChunMing) Zhou" <David1.Zhou@amd.com> > Cc: Harry Wentland <harry.wentland@amd.com> > Cc: amd-gfx@lists.freedesktop.org > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 33 +++++++++-------- > drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 3 +- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++-- > .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 5 +-- > drivers/gpu/drm/ast/ast_mode.c | 3 +- > drivers/gpu/drm/bochs/bochs_kms.c | 3 +- > drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 3 +- > drivers/gpu/drm/bridge/tc358767.c | 3 +- > drivers/gpu/drm/cirrus/cirrus_mode.c | 5 +-- > drivers/gpu/drm/drm_atomic_helper.c | 16 ++++++--- > drivers/gpu/drm/drm_crtc_helper.c | 3 +- > drivers/gpu/drm/drm_fb_helper.c | 41 ++++++++++++---------- > drivers/gpu/drm/gma500/gma_display.c | 3 +- > drivers/gpu/drm/gma500/mdfld_dsi_output.c | 5 +-- > drivers/gpu/drm/gma500/psb_intel_drv.h | 3 +- > drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 3 +- > drivers/gpu/drm/i2c/tda998x_drv.c | 3 +- > drivers/gpu/drm/i915/intel_dp_mst.c | 9 +++-- > drivers/gpu/drm/imx/imx-ldb.c | 5 +-- > drivers/gpu/drm/imx/imx-tve.c | 5 +-- > drivers/gpu/drm/imx/parallel-display.c | 5 +-- > drivers/gpu/drm/mediatek/mtk_hdmi.c | 3 +- > drivers/gpu/drm/mgag200/mgag200_mode.c | 5 +-- > drivers/gpu/drm/msm/dsi/dsi_manager.c | 3 +- > drivers/gpu/drm/nouveau/dispnv50/disp.c | 3 +- > drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +- > drivers/gpu/drm/qxl/qxl_display.c | 3 +- > drivers/gpu/drm/radeon/radeon_connectors.c | 40 +++++++++++---------- > drivers/gpu/drm/radeon/radeon_dp_mst.c | 5 +-- > drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 3 +- > drivers/gpu/drm/tilcdc/tilcdc_panel.c | 5 +-- > drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 5 +-- > drivers/gpu/drm/udl/udl_connector.c | 3 +- > drivers/staging/vboxvideo/vbox_mode.c | 5 +-- > include/drm/drm_atomic_helper.h | 3 +- > include/drm/drm_modeset_helper_vtables.h | 6 ++-- > 36 files changed, 155 insertions(+), 106 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > index 8e66851eb427..3dfa50ec2589 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > @@ -135,7 +135,8 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) > else { > const struct drm_connector_helper_funcs *connector_funcs = > connector->helper_private; > - struct drm_encoder *encoder = connector_funcs->best_encoder(connector); > + struct drm_encoder *encoder = connector_funcs->best_encoder(connector, > + NULL); > struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder); > struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv; > > @@ -218,7 +219,7 @@ amdgpu_connector_update_scratch_regs(struct drm_connector *connector, > bool connected; > int i; > > - best_encoder = connector_funcs->best_encoder(connector); > + best_encoder = connector_funcs->best_encoder(connector, NULL); > > for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { > if (connector->encoder_ids[i] == 0) > @@ -358,7 +359,8 @@ static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) > } > > static struct drm_encoder * > -amdgpu_connector_best_single_encoder(struct drm_connector *connector) > +amdgpu_connector_best_single_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > > @@ -370,7 +372,7 @@ amdgpu_connector_best_single_encoder(struct drm_connector *connector) > > static void amdgpu_get_native_mode(struct drm_connector *connector) > { > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > struct amdgpu_encoder *amdgpu_encoder; > > if (encoder == NULL) > @@ -593,7 +595,7 @@ static int amdgpu_connector_set_property(struct drm_connector *connector, > amdgpu_encoder = to_amdgpu_encoder(connector->encoder); > } else { > const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; > - amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector)); > + amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector, NULL)); > } > > switch (val) { > @@ -663,7 +665,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) > amdgpu_connector_get_edid(connector); > ret = amdgpu_connector_ddc_get_modes(connector); > if (ret > 0) { > - encoder = amdgpu_connector_best_single_encoder(connector); > + encoder = amdgpu_connector_best_single_encoder(connector, NULL); > if (encoder) { > amdgpu_connector_fixup_lcd_native_mode(encoder, connector); > /* add scaled modes */ > @@ -672,7 +674,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) > return ret; > } > > - encoder = amdgpu_connector_best_single_encoder(connector); > + encoder = amdgpu_connector_best_single_encoder(connector, NULL); > if (!encoder) > return 0; > > @@ -694,7 +696,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) > static enum drm_mode_status amdgpu_connector_lvds_mode_valid(struct drm_connector *connector, > struct drm_display_mode *mode) > { > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > > if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) > return MODE_PANEL; > @@ -725,7 +727,7 @@ static enum drm_connector_status > amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force) > { > struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > enum drm_connector_status ret = connector_status_disconnected; > int r; > > @@ -798,7 +800,7 @@ static int amdgpu_connector_set_lcd_property(struct drm_connector *connector, > amdgpu_encoder = to_amdgpu_encoder(connector->encoder); > else { > const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; > - amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector)); > + amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector, NULL)); > } > > switch (value) { > @@ -873,7 +875,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) > return connector_status_disconnected; > } > > - encoder = amdgpu_connector_best_single_encoder(connector); > + encoder = amdgpu_connector_best_single_encoder(connector, NULL); > if (!encoder) > ret = connector_status_disconnected; > > @@ -1130,7 +1132,8 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) > > /* okay need to be smart in here about which encoder to pick */ > static struct drm_encoder * > -amdgpu_connector_dvi_encoder(struct drm_connector *connector) > +amdgpu_connector_dvi_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); > @@ -1224,7 +1227,7 @@ static int amdgpu_connector_dp_get_modes(struct drm_connector *connector) > { > struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); > struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv; > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > int ret; > > if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || > @@ -1363,7 +1366,7 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) > struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); > enum drm_connector_status ret = connector_status_disconnected; > struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv; > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > int r; > > if (!drm_kms_helper_is_poll_worker()) { > @@ -1458,7 +1461,7 @@ static enum drm_mode_status amdgpu_connector_dp_mode_valid(struct drm_connector > > if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || > (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { > - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); > + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); > > if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) > return MODE_PANEL; > diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c > index dbf2ccd0c744..b02ce39e65b7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c > +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c > @@ -267,7 +267,8 @@ static int dce_virtual_early_init(void *handle) > } > > static struct drm_encoder * > -dce_virtual_encoder(struct drm_connector *connector) > +dce_virtual_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > struct drm_encoder *encoder; > 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 3e1c2a04d669..e56ed4e5818f 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -2758,7 +2758,8 @@ static const struct drm_connector_funcs amdgpu_dm_connector_funcs = { > .atomic_get_property = amdgpu_dm_connector_atomic_get_property > }; > > -static struct drm_encoder *best_encoder(struct drm_connector *connector) > +static struct drm_encoder *best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > struct drm_mode_object *obj; > @@ -3304,7 +3305,7 @@ static void amdgpu_dm_get_native_mode(struct drm_connector *connector) > struct drm_encoder *encoder; > struct amdgpu_encoder *amdgpu_encoder; > > - encoder = helper->best_encoder(connector); > + encoder = helper->best_encoder(connector, NULL); > > if (encoder == NULL) > return; > @@ -3438,7 +3439,7 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) > struct drm_encoder *encoder; > struct edid *edid = amdgpu_dm_connector->edid; > > - encoder = helper->best_encoder(connector); > + encoder = helper->best_encoder(connector, NULL); > amdgpu_dm_connector_ddc_get_modes(connector, edid); > amdgpu_dm_connector_add_common_modes(encoder, connector); > > 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 4304d9e408b8..4544a1401caf 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 > @@ -269,7 +269,8 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) > return ret; > } > > -static struct drm_encoder *dm_mst_best_encoder(struct drm_connector *connector) > +static struct drm_encoder *dm_mst_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); > > @@ -302,7 +303,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector) > const struct drm_connector_helper_funcs *connector_funcs = > connector->base.helper_private; > struct drm_encoder *enc_master = > - connector_funcs->best_encoder(&connector->base); > + connector_funcs->best_encoder(&connector->base, NULL); > > DRM_DEBUG_KMS("enc master is %p\n", enc_master); > amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL); > diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c > index 036dff8a1f33..d5899aa41d37 100644 > --- a/drivers/gpu/drm/ast/ast_mode.c > +++ b/drivers/gpu/drm/ast/ast_mode.c > @@ -709,7 +709,8 @@ static void ast_encoder_destroy(struct drm_encoder *encoder) > } > > > -static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connector) > +static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > /* pick the encoder ids */ > diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c > index 233980a78591..dc80a238feef 100644 > --- a/drivers/gpu/drm/bochs/bochs_kms.c > +++ b/drivers/gpu/drm/bochs/bochs_kms.c > @@ -208,7 +208,8 @@ static enum drm_mode_status bochs_connector_mode_valid(struct drm_connector *con > } > > static struct drm_encoder * > -bochs_connector_best_encoder(struct drm_connector *connector) > +bochs_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > /* pick the encoder ids */ > diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > index 2bcbfadb6ac5..0706471c8c63 100644 > --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > @@ -1137,7 +1137,8 @@ static int analogix_dp_get_modes(struct drm_connector *connector) > } > > static struct drm_encoder * > -analogix_dp_best_encoder(struct drm_connector *connector) > +analogix_dp_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct analogix_dp_device *dp = to_dp(connector); > > diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c > index 0fd9cf27542c..7cd954226fe3 100644 > --- a/drivers/gpu/drm/bridge/tc358767.c > +++ b/drivers/gpu/drm/bridge/tc358767.c > @@ -1155,7 +1155,8 @@ static void tc_connector_set_polling(struct tc_data *tc, > } > > static struct drm_encoder * > -tc_connector_best_encoder(struct drm_connector *connector) > +tc_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct tc_data *tc = connector_to_tc(connector); > > diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c > index b529f8c8e2a6..378ebc3f25e8 100644 > --- a/drivers/gpu/drm/cirrus/cirrus_mode.c > +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c > @@ -451,8 +451,9 @@ static int cirrus_vga_get_modes(struct drm_connector *connector) > return count; > } > > -static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector > - *connector) > +static struct drm_encoder * > +cirrus_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > /* pick the encoder ids */ > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c > index 232fa11a5e31..bd3aebbfd5b4 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -115,9 +115,11 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, > if (funcs->atomic_best_encoder) > new_encoder = funcs->atomic_best_encoder(connector, new_conn_state); > else if (funcs->best_encoder) > - new_encoder = funcs->best_encoder(connector); > + new_encoder = funcs->best_encoder(connector, > + new_conn_state->crtc); > else > - new_encoder = drm_atomic_helper_best_encoder(connector); > + new_encoder = drm_atomic_helper_best_encoder(connector, > + new_conn_state->crtc); > > if (new_encoder) { > if (encoder_mask & (1 << drm_encoder_index(new_encoder))) { > @@ -312,9 +314,11 @@ update_connector_routing(struct drm_atomic_state *state, > new_encoder = funcs->atomic_best_encoder(connector, > new_connector_state); > else if (funcs->best_encoder) > - new_encoder = funcs->best_encoder(connector); > + new_encoder = funcs->best_encoder(connector, > + new_connector_state->crtc); > else > - new_encoder = drm_atomic_helper_best_encoder(connector); > + new_encoder = drm_atomic_helper_best_encoder(connector, > + new_connector_state->crtc); > > if (!new_encoder) { > DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n", > @@ -3318,13 +3322,15 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip_target); > * drm_atomic_helper_best_encoder - Helper for > * &drm_connector_helper_funcs.best_encoder callback > * @connector: Connector control structure > + * @crtc: DRM crtc > * > * This is a &drm_connector_helper_funcs.best_encoder callback helper for > * connectors that support exactly 1 encoder, statically determined at driver > * init time. > */ > struct drm_encoder * > -drm_atomic_helper_best_encoder(struct drm_connector *connector) > +drm_atomic_helper_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > WARN_ON(connector->encoder_ids[1]); > return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); > diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c > index 5a84c3bc915d..f9318fc11fb1 100644 > --- a/drivers/gpu/drm/drm_crtc_helper.c > +++ b/drivers/gpu/drm/drm_crtc_helper.c > @@ -637,7 +637,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set, > new_encoder = connector->encoder; > for (ro = 0; ro < set->num_connectors; ro++) { > if (set->connectors[ro] == connector) { > - new_encoder = connector_funcs->best_encoder(connector); > + new_encoder = connector_funcs->best_encoder(connector, > + set->crtc); > /* if we can't get an encoder for a connector > we are setting now - then fail */ > if (new_encoder == NULL) > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c > index cab14f253384..ce91ae12cccb 100644 > --- a/drivers/gpu/drm/drm_fb_helper.c > +++ b/drivers/gpu/drm/drm_fb_helper.c > @@ -2331,9 +2331,8 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, > int c, o; > struct drm_connector *connector; > const struct drm_connector_helper_funcs *connector_funcs; > - struct drm_encoder *encoder; > int my_score, best_score, score; > - struct drm_fb_helper_crtc **crtcs, *crtc; > + struct drm_fb_helper_crtc **crtcs; > struct drm_fb_helper_connector *fb_helper_conn; > > if (n == fb_helper->connector_count) > @@ -2362,28 +2361,32 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, > > connector_funcs = connector->helper_private; > > - /* > - * If the DRM device implements atomic hooks and ->best_encoder() is > - * NULL we fallback to the default drm_atomic_helper_best_encoder() > - * helper. > - */ > - if (drm_drv_uses_atomic_modeset(fb_helper->dev) && > - !connector_funcs->best_encoder) > - encoder = drm_atomic_helper_best_encoder(connector); > - else > - encoder = connector_funcs->best_encoder(connector); > - > - if (!encoder) > - goto out; > - > /* > * select a crtc for this connector and then attempt to configure > * remaining connectors > */ > for (c = 0; c < fb_helper->crtc_count; c++) { > - crtc = &fb_helper->crtc_info[c]; > + struct drm_encoder *encoder; > + struct drm_fb_helper_crtc *crtc = &fb_helper->crtc_info[c]; > > - if ((encoder->possible_crtcs & (1 << c)) == 0) > + /* > + * If the DRM device implements atomic hooks and ->best_encoder() is > + * NULL we fallback to the default drm_atomic_helper_best_encoder() > + * helper. > + */ > + if (drm_drv_uses_atomic_modeset(fb_helper->dev) && > + !connector_funcs->best_encoder) > + encoder = drm_atomic_helper_best_encoder(connector, > + crtc->mode_set.crtc); > + else > + encoder = connector_funcs->best_encoder(connector, > + crtc->mode_set.crtc); > + > + if (!encoder) > + continue; > + > + if ((encoder->possible_crtcs & > + drm_crtc_mask(crtc->mode_set.crtc)) == 0) > continue; > > for (o = 0; o < n; o++) > @@ -2410,7 +2413,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, > sizeof(struct drm_fb_helper_crtc *)); > } > } > -out: > + > kfree(crtcs); > return best_score; > } > diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c > index c8f071c47daf..251b64653dc8 100644 > --- a/drivers/gpu/drm/gma500/gma_display.c > +++ b/drivers/gpu/drm/gma500/gma_display.c > @@ -652,7 +652,8 @@ void gma_encoder_destroy(struct drm_encoder *encoder) > } > > /* Currently there is only a 1:1 mapping of encoders and connectors */ > -struct drm_encoder *gma_best_encoder(struct drm_connector *connector) > +struct drm_encoder *gma_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct gma_encoder *gma_encoder = gma_attached_encoder(connector); > > diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c > index fe020926ea4f..9e5b059a9e5b 100644 > --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c > +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c > @@ -377,8 +377,9 @@ static enum drm_mode_status mdfld_dsi_connector_mode_valid(struct drm_connector > return MODE_OK; > } > > -static struct drm_encoder *mdfld_dsi_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +mdfld_dsi_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct mdfld_dsi_connector *dsi_connector = > mdfld_dsi_connector(connector); > diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h > index e05e5399af2d..e903525b9d30 100644 > --- a/drivers/gpu/drm/gma500/psb_intel_drv.h > +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h > @@ -230,7 +230,8 @@ extern void oaktrail_lvds_i2c_init(struct drm_encoder *encoder); > extern void mid_dsi_init(struct drm_device *dev, > struct psb_intel_mode_device *mode_dev, int dsi_num); > > -extern struct drm_encoder *gma_best_encoder(struct drm_connector *connector); > +extern struct drm_encoder *gma_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc); > extern void gma_connector_attach_encoder(struct gma_connector *connector, > struct gma_encoder *encoder); > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c > index d2f4749ebf8d..89a0104f9855 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c > +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c > @@ -34,7 +34,8 @@ static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *con > } > > static struct drm_encoder * > -hibmc_connector_best_encoder(struct drm_connector *connector) > +hibmc_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); > } > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c > index 0038c976536a..422347d977b4 100644 > --- a/drivers/gpu/drm/i2c/tda998x_drv.c > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c > @@ -1267,7 +1267,8 @@ static enum drm_mode_status tda998x_connector_mode_valid(struct drm_connector *c > } > > static struct drm_encoder * > -tda998x_connector_best_encoder(struct drm_connector *connector) > +tda998x_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct tda998x_priv *priv = conn_to_tda998x_priv(connector); > > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c > index 5890500a3a8b..d9119d516579 100644 > --- a/drivers/gpu/drm/i915/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c > @@ -403,20 +403,23 @@ static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *c > return &intel_dp->mst_encoders[crtc->pipe]->base.base; > } > > -static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector) > +static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector, > + struct drm_crtc *_crtc) > { > struct intel_connector *intel_connector = to_intel_connector(connector); > struct intel_dp *intel_dp = intel_connector->mst_port; > + struct intel_crtc *crtc = to_intel_crtc(_crtc); > + > if (!intel_dp) > return NULL; > - return &intel_dp->mst_encoders[0]->base.base; > + return &intel_dp->mst_encoders[crtc->pipe]->base.base; > } > > static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { > .get_modes = intel_dp_mst_get_modes, > .mode_valid = intel_dp_mst_mode_valid, > .atomic_best_encoder = intel_mst_atomic_best_encoder, > - .best_encoder = intel_mst_best_encoder, > + .best_encoder = intel_mst_best_encoder, /* only for fb_helper */ > .atomic_check = intel_dp_mst_atomic_check, > }; > > diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c > index 56dd7a9a8e25..f1523cccc090 100644 > --- a/drivers/gpu/drm/imx/imx-ldb.c > +++ b/drivers/gpu/drm/imx/imx-ldb.c > @@ -163,8 +163,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) > return num_modes; > } > > -static struct drm_encoder *imx_ldb_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +imx_ldb_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); > > diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c > index bc27c2699464..71f49ac835ec 100644 > --- a/drivers/gpu/drm/imx/imx-tve.c > +++ b/drivers/gpu/drm/imx/imx-tve.c > @@ -265,8 +265,9 @@ static int imx_tve_connector_mode_valid(struct drm_connector *connector, > return MODE_BAD; > } > > -static struct drm_encoder *imx_tve_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +imx_tve_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct imx_tve *tve = con_to_tve(connector); > > diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c > index aedecda9728a..438f95dee73e 100644 > --- a/drivers/gpu/drm/imx/parallel-display.c > +++ b/drivers/gpu/drm/imx/parallel-display.c > @@ -89,8 +89,9 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) > return num_modes; > } > > -static struct drm_encoder *imx_pd_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +imx_pd_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct imx_parallel_display *imxpd = con_to_imxpd(connector); > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c > index 59a11026dceb..c0578779fb19 100644 > --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c > @@ -1253,7 +1253,8 @@ static int mtk_hdmi_conn_mode_valid(struct drm_connector *conn, > return drm_mode_validate_size(mode, 0x1fff, 0x1fff); > } > > -static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn) > +static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn, > + struct drm_crtc *crtc) > { > struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); > > diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c > index 8918539a19aa..4059f04030ee 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_mode.c > +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c > @@ -1664,8 +1664,9 @@ static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector, > return MODE_OK; > } > > -static struct drm_encoder *mga_connector_best_encoder(struct drm_connector > - *connector) > +static struct drm_encoder * > +mga_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > /* pick the encoder ids */ > diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c > index 4cb1cb68878b..8cbede64819e 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c > @@ -426,7 +426,8 @@ static int dsi_mgr_connector_mode_valid(struct drm_connector *connector, > } > > static struct drm_encoder * > -dsi_mgr_connector_best_encoder(struct drm_connector *connector) > +dsi_mgr_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int id = dsi_mgr_connector_get_id(connector); > struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); > diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c > index b83465ae7c1b..a9bacb0a1e16 100644 > --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c > +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c > @@ -826,7 +826,8 @@ nv50_mstc_atomic_best_encoder(struct drm_connector *connector, > } > > static struct drm_encoder * > -nv50_mstc_best_encoder(struct drm_connector *connector) > +nv50_mstc_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct nv50_mstc *mstc = nv50_mstc(connector); > if (mstc->port) { > diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c > index 7b557c354307..ee4bf532b932 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_connector.c > +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c > @@ -1063,7 +1063,8 @@ nouveau_connector_mode_valid(struct drm_connector *connector, > } > > static struct drm_encoder * > -nouveau_connector_best_encoder(struct drm_connector *connector) > +nouveau_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct nouveau_connector *nv_connector = nouveau_connector(connector); > > diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c > index 768207fbbae3..fa5c84f35531 100644 > --- a/drivers/gpu/drm/qxl/qxl_display.c > +++ b/drivers/gpu/drm/qxl/qxl_display.c > @@ -978,7 +978,8 @@ static enum drm_mode_status qxl_conn_mode_valid(struct drm_connector *connector, > return MODE_BAD; > } > > -static struct drm_encoder *qxl_best_encoder(struct drm_connector *connector) > +static struct drm_encoder *qxl_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct qxl_output *qxl_output = > drm_connector_to_qxl_output(connector); > diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c > index 2aea2bdff99b..8bf7298dccb3 100644 > --- a/drivers/gpu/drm/radeon/radeon_connectors.c > +++ b/drivers/gpu/drm/radeon/radeon_connectors.c > @@ -158,7 +158,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) > else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { > const struct drm_connector_helper_funcs *connector_funcs = > connector->helper_private; > - struct drm_encoder *encoder = connector_funcs->best_encoder(connector); > + struct drm_encoder *encoder = connector_funcs->best_encoder(connector, NULL); > struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); > struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; > > @@ -250,7 +250,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c > bool connected; > int i; > > - best_encoder = connector_funcs->best_encoder(connector); > + best_encoder = connector_funcs->best_encoder(connector, NULL); > > for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { > if (connector->encoder_ids[i] == 0) > @@ -391,7 +391,8 @@ static int radeon_ddc_get_modes(struct drm_connector *connector) > return 0; > } > > -static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) > +static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > /* pick the encoder ids */ > @@ -402,7 +403,7 @@ static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *conn > > static void radeon_get_native_mode(struct drm_connector *connector) > { > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > struct radeon_encoder *radeon_encoder; > > if (encoder == NULL) > @@ -728,7 +729,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct > radeon_encoder = to_radeon_encoder(connector->encoder); > else { > const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; > - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); > + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); > } > > switch (val) { > @@ -755,7 +756,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct > radeon_encoder = to_radeon_encoder(connector->encoder); > else { > const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; > - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); > + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); > } > > if (radeon_encoder->output_csc == val) > @@ -824,7 +825,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) > radeon_connector_get_edid(connector); > ret = radeon_ddc_get_modes(connector); > if (ret > 0) { > - encoder = radeon_best_single_encoder(connector); > + encoder = radeon_best_single_encoder(connector, NULL); > if (encoder) { > radeon_fixup_lvds_native_mode(encoder, connector); > /* add scaled modes */ > @@ -833,7 +834,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) > return ret; > } > > - encoder = radeon_best_single_encoder(connector); > + encoder = radeon_best_single_encoder(connector, NULL); > if (!encoder) > return 0; > > @@ -855,7 +856,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) > static enum drm_mode_status radeon_lvds_mode_valid(struct drm_connector *connector, > struct drm_display_mode *mode) > { > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > > if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) > return MODE_PANEL; > @@ -888,7 +889,7 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) > struct drm_device *dev = connector->dev; > struct radeon_device *rdev = dev->dev_private; > struct radeon_connector *radeon_connector = to_radeon_connector(connector); > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > enum drm_connector_status ret = connector_status_disconnected; > int r; > > @@ -965,7 +966,7 @@ static int radeon_lvds_set_property(struct drm_connector *connector, > radeon_encoder = to_radeon_encoder(connector->encoder); > else { > const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; > - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); > + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); > } > > switch (value) { > @@ -1044,7 +1045,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) > return connector_status_disconnected; > } > > - encoder = radeon_best_single_encoder(connector); > + encoder = radeon_best_single_encoder(connector, NULL); > if (!encoder) > ret = connector_status_disconnected; > > @@ -1139,7 +1140,7 @@ static int radeon_tv_get_modes(struct drm_connector *connector) > struct drm_display_mode *tv_mode; > struct drm_encoder *encoder; > > - encoder = radeon_best_single_encoder(connector); > + encoder = radeon_best_single_encoder(connector, NULL); > if (!encoder) > return 0; > > @@ -1182,7 +1183,7 @@ radeon_tv_detect(struct drm_connector *connector, bool force) > return connector_status_disconnected; > } > > - encoder = radeon_best_single_encoder(connector); > + encoder = radeon_best_single_encoder(connector, NULL); > if (!encoder) > ret = connector_status_disconnected; > else { > @@ -1439,7 +1440,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) > const struct drm_connector_helper_funcs *connector_funcs = > connector->helper_private; > > - encoder = connector_funcs->best_encoder(connector); > + encoder = connector_funcs->best_encoder(connector, NULL); > if (encoder && (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)) { > radeon_connector_get_edid(connector); > radeon_audio_detect(connector, encoder, ret); > @@ -1456,7 +1457,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) > } > > /* okay need to be smart in here about which encoder to pick */ > -static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) > +static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > struct radeon_connector *radeon_connector = to_radeon_connector(connector); > @@ -1556,7 +1558,7 @@ static int radeon_dp_get_modes(struct drm_connector *connector) > { > struct radeon_connector *radeon_connector = to_radeon_connector(connector); > struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > int ret; > > if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || > @@ -1695,7 +1697,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) > struct radeon_connector *radeon_connector = to_radeon_connector(connector); > enum drm_connector_status ret = connector_status_disconnected; > struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > int r; > > if (radeon_dig_connector->is_mst) > @@ -1812,7 +1814,7 @@ static enum drm_mode_status radeon_dp_mode_valid(struct drm_connector *connector > > if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || > (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { > - struct drm_encoder *encoder = radeon_best_single_encoder(connector); > + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); > > if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) > return MODE_PANEL; > diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c > index cd8a3ee16649..fd5a0dae0e1f 100644 > --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c > +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c > @@ -224,7 +224,8 @@ radeon_dp_mst_mode_valid(struct drm_connector *connector, > } > > static struct > -drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector) > +drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct radeon_connector *radeon_connector = to_radeon_connector(connector); > > @@ -613,7 +614,7 @@ radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector) > struct radeon_encoder_mst *mst_enc; > struct drm_encoder *encoder; > const struct drm_connector_helper_funcs *connector_funcs = connector->base.helper_private; > - struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base); > + struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base, NULL); > > DRM_DEBUG_KMS("enc master is %p\n", enc_master); > radeon_encoder = kzalloc(sizeof(*radeon_encoder), GFP_KERNEL); > diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c > index e7738939a86d..cdc991d5c28e 100644 > --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c > @@ -668,7 +668,8 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector) > } > > static struct drm_encoder * > -shmob_drm_connector_best_encoder(struct drm_connector *connector) > +shmob_drm_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct shmob_drm_connector *scon = to_shmob_connector(connector); > > diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c > index d616d64a6725..197962eca1af 100644 > --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c > +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c > @@ -178,8 +178,9 @@ static int panel_connector_mode_valid(struct drm_connector *connector, > return tilcdc_crtc_mode_valid(priv->crtc, mode); > } > > -static struct drm_encoder *panel_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +panel_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct panel_connector *panel_connector = to_panel_connector(connector); > return panel_connector->encoder; > diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c > index c45cabb38db0..0ef8221c5334 100644 > --- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c > +++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c > @@ -191,8 +191,9 @@ static int tfp410_connector_mode_valid(struct drm_connector *connector, > return tilcdc_crtc_mode_valid(priv->crtc, mode); > } > > -static struct drm_encoder *tfp410_connector_best_encoder( > - struct drm_connector *connector) > +static struct drm_encoder * > +tfp410_connector_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector); > return tfp410_connector->encoder; > diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c > index 09dc585aa46f..803ae6515892 100644 > --- a/drivers/gpu/drm/udl/udl_connector.c > +++ b/drivers/gpu/drm/udl/udl_connector.c > @@ -145,7 +145,8 @@ udl_detect(struct drm_connector *connector, bool force) > } > > static struct drm_encoder* > -udl_best_single_encoder(struct drm_connector *connector) > +udl_best_single_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > return drm_encoder_find(connector->dev, NULL, enc_id); > diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c > index b265fe924556..bf0e93705e1c 100644 > --- a/drivers/staging/vboxvideo/vbox_mode.c > +++ b/drivers/staging/vboxvideo/vbox_mode.c > @@ -370,8 +370,9 @@ static void vbox_encoder_destroy(struct drm_encoder *encoder) > kfree(encoder); > } > > -static struct drm_encoder *vbox_best_single_encoder(struct drm_connector > - *connector) > +static struct drm_encoder * > +vbox_best_single_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc) > { > int enc_id = connector->encoder_ids[0]; > > diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h > index 26aaba58d6ce..e0f00d43ed63 100644 > --- a/include/drm/drm_atomic_helper.h > +++ b/include/drm/drm_atomic_helper.h > @@ -143,7 +143,8 @@ int drm_atomic_helper_page_flip_target( > uint32_t target, > struct drm_modeset_acquire_ctx *ctx); > struct drm_encoder * > -drm_atomic_helper_best_encoder(struct drm_connector *connector); > +drm_atomic_helper_best_encoder(struct drm_connector *connector, > + struct drm_crtc *crtc); > > /* default implementations for state handling */ > void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h > index 35e2a3a79fc5..a9b3a2c50877 100644 > --- a/include/drm/drm_modeset_helper_vtables.h > +++ b/include/drm/drm_modeset_helper_vtables.h > @@ -885,7 +885,8 @@ struct drm_connector_helper_funcs { > /** > * @best_encoder: > * > - * This function should select the best encoder for the given connector. > + * This function should select the best encoder for the given connector > + * and crtc. For some driver internal use crtc may be NULL. > * > * This function is used by both the atomic helpers (in the > * drm_atomic_helper_check_modeset() function) and in the legacy CRTC > @@ -911,7 +912,8 @@ struct drm_connector_helper_funcs { > * will ensure that encoders aren't used twice, drivers should not check > * for this. > */ > - struct drm_encoder *(*best_encoder)(struct drm_connector *connector); > + struct drm_encoder *(*best_encoder)(struct drm_connector *connector, > + struct drm_crtc *crtc); > > /** > * @atomic_best_encoder: > -- > 2.16.4 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel
On Tue, Jun 26, 2018 at 05:23:25PM +0200, Daniel Vetter wrote: > On Fri, Jun 15, 2018 at 10:52:21PM +0300, Ville Syrjala wrote: > > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > > > To pick the correct MST encoder i915 wants to know which crtc is going > > to be feeding us. To that end let's pass the crtc to the .best_encoder() > > hook. The atomic variant already knows the crtc via the connector state, > > but the non-atomic hooks is still being used by the fb_helper even on > > atomic drivers. > > Can't we instead fix the fb helpers to use atomic_best_encoder? We'd need a connector state for that. Not sure we want to construct a fake one on demand or something. > Or just > drop that code, userspace doesn't really know any better either and just > needs to figure this out without the help of ->best_encoder, so it should > be possible. I have to admit I don't even remmber how userspace does this. OK, yeah so each connector has a list of encoders and each encoder has the possible_crtcs bitmask. So we should be able to just iterate through all the encoders for the connector. Not sure there couldn't be some some false positives if best_encoder() doesn't quite agree with the answer for some reason. But yeah, this does seem like a nicer option because we can then nuke the extra .best_encoder() hook for i915 mst. Now the question becomes whether I get to review the connecor->encoder_ids[] assignments in every driver. I suppose they should be mostly OK if userspace manages to work.
On 2018-06-26 11:01 AM, Harry Wentland wrote: > On 2018-06-15 03:52 PM, Ville Syrjala wrote: >> From: Ville Syrjälä <ville.syrjala@linux.intel.com> >> >> To pick the correct MST encoder i915 wants to know which crtc is going >> to be feeding us. To that end let's pass the crtc to the .best_encoder() >> hook. The atomic variant already knows the crtc via the connector state, >> but the non-atomic hooks is still being used by the fb_helper even on >> atomic drivers. >> >> This allows us to fix up the possible_crtcs bitmask for the i915 MST >> encoders. We have one encoder for each crtc+port combination, and thus >> we have to know both the connector and the crtc to pick the right one. >> This has only worked so far because every MST encoder lied in its >> possible_crtcs bitmask that they can be driven by any crtc. >> >> I took the easy way out and passed NULL as the crtc for all the driver >> internal uses of .best_encoder() in the amdgpu/radeon drivers. None of >> the other drivers have such internal uses. The other callers >> (crtc_helper, atomic_helper, fb_helper) will pass in the proper crtc. >> but no one besides i915 will currently look at it. >> >> Cc: Alex Deucher <alexander.deucher@amd.com> >> Cc: "Christian König" <christian.koenig@amd.com> >> Cc: "David (ChunMing) Zhou" <David1.Zhou@amd.com> >> Cc: Harry Wentland <harry.wentland@amd.com> >> Cc: amd-gfx@lists.freedesktop.org >> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > amdgpu parts are > Acked-by: Harry Wentland <harry.wentland@amd.com> > Upgrading after proper review of the entire patch Reviewed-by: Harry Wentland <harry.wentland@amd.com> Harry > Harry > >> --- >> drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 33 +++++++++-------- >> drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 3 +- >> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++-- >> .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 5 +-- >> drivers/gpu/drm/ast/ast_mode.c | 3 +- >> drivers/gpu/drm/bochs/bochs_kms.c | 3 +- >> drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 3 +- >> drivers/gpu/drm/bridge/tc358767.c | 3 +- >> drivers/gpu/drm/cirrus/cirrus_mode.c | 5 +-- >> drivers/gpu/drm/drm_atomic_helper.c | 16 ++++++--- >> drivers/gpu/drm/drm_crtc_helper.c | 3 +- >> drivers/gpu/drm/drm_fb_helper.c | 41 ++++++++++++---------- >> drivers/gpu/drm/gma500/gma_display.c | 3 +- >> drivers/gpu/drm/gma500/mdfld_dsi_output.c | 5 +-- >> drivers/gpu/drm/gma500/psb_intel_drv.h | 3 +- >> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 3 +- >> drivers/gpu/drm/i2c/tda998x_drv.c | 3 +- >> drivers/gpu/drm/i915/intel_dp_mst.c | 9 +++-- >> drivers/gpu/drm/imx/imx-ldb.c | 5 +-- >> drivers/gpu/drm/imx/imx-tve.c | 5 +-- >> drivers/gpu/drm/imx/parallel-display.c | 5 +-- >> drivers/gpu/drm/mediatek/mtk_hdmi.c | 3 +- >> drivers/gpu/drm/mgag200/mgag200_mode.c | 5 +-- >> drivers/gpu/drm/msm/dsi/dsi_manager.c | 3 +- >> drivers/gpu/drm/nouveau/dispnv50/disp.c | 3 +- >> drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +- >> drivers/gpu/drm/qxl/qxl_display.c | 3 +- >> drivers/gpu/drm/radeon/radeon_connectors.c | 40 +++++++++++---------- >> drivers/gpu/drm/radeon/radeon_dp_mst.c | 5 +-- >> drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 3 +- >> drivers/gpu/drm/tilcdc/tilcdc_panel.c | 5 +-- >> drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 5 +-- >> drivers/gpu/drm/udl/udl_connector.c | 3 +- >> drivers/staging/vboxvideo/vbox_mode.c | 5 +-- >> include/drm/drm_atomic_helper.h | 3 +- >> include/drm/drm_modeset_helper_vtables.h | 6 ++-- >> 36 files changed, 155 insertions(+), 106 deletions(-) >> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c >> index 8e66851eb427..3dfa50ec2589 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c >> @@ -135,7 +135,8 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) >> else { >> const struct drm_connector_helper_funcs *connector_funcs = >> connector->helper_private; >> - struct drm_encoder *encoder = connector_funcs->best_encoder(connector); >> + struct drm_encoder *encoder = connector_funcs->best_encoder(connector, >> + NULL); >> struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder); >> struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv; >> >> @@ -218,7 +219,7 @@ amdgpu_connector_update_scratch_regs(struct drm_connector *connector, >> bool connected; >> int i; >> >> - best_encoder = connector_funcs->best_encoder(connector); >> + best_encoder = connector_funcs->best_encoder(connector, NULL); >> >> for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { >> if (connector->encoder_ids[i] == 0) >> @@ -358,7 +359,8 @@ static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) >> } >> >> static struct drm_encoder * >> -amdgpu_connector_best_single_encoder(struct drm_connector *connector) >> +amdgpu_connector_best_single_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> >> @@ -370,7 +372,7 @@ amdgpu_connector_best_single_encoder(struct drm_connector *connector) >> >> static void amdgpu_get_native_mode(struct drm_connector *connector) >> { >> - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); >> + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); >> struct amdgpu_encoder *amdgpu_encoder; >> >> if (encoder == NULL) >> @@ -593,7 +595,7 @@ static int amdgpu_connector_set_property(struct drm_connector *connector, >> amdgpu_encoder = to_amdgpu_encoder(connector->encoder); >> } else { >> const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; >> - amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector)); >> + amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector, NULL)); >> } >> >> switch (val) { >> @@ -663,7 +665,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) >> amdgpu_connector_get_edid(connector); >> ret = amdgpu_connector_ddc_get_modes(connector); >> if (ret > 0) { >> - encoder = amdgpu_connector_best_single_encoder(connector); >> + encoder = amdgpu_connector_best_single_encoder(connector, NULL); >> if (encoder) { >> amdgpu_connector_fixup_lcd_native_mode(encoder, connector); >> /* add scaled modes */ >> @@ -672,7 +674,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) >> return ret; >> } >> >> - encoder = amdgpu_connector_best_single_encoder(connector); >> + encoder = amdgpu_connector_best_single_encoder(connector, NULL); >> if (!encoder) >> return 0; >> >> @@ -694,7 +696,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) >> static enum drm_mode_status amdgpu_connector_lvds_mode_valid(struct drm_connector *connector, >> struct drm_display_mode *mode) >> { >> - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); >> + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); >> >> if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) >> return MODE_PANEL; >> @@ -725,7 +727,7 @@ static enum drm_connector_status >> amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force) >> { >> struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); >> - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); >> + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); >> enum drm_connector_status ret = connector_status_disconnected; >> int r; >> >> @@ -798,7 +800,7 @@ static int amdgpu_connector_set_lcd_property(struct drm_connector *connector, >> amdgpu_encoder = to_amdgpu_encoder(connector->encoder); >> else { >> const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; >> - amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector)); >> + amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector, NULL)); >> } >> >> switch (value) { >> @@ -873,7 +875,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) >> return connector_status_disconnected; >> } >> >> - encoder = amdgpu_connector_best_single_encoder(connector); >> + encoder = amdgpu_connector_best_single_encoder(connector, NULL); >> if (!encoder) >> ret = connector_status_disconnected; >> >> @@ -1130,7 +1132,8 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) >> >> /* okay need to be smart in here about which encoder to pick */ >> static struct drm_encoder * >> -amdgpu_connector_dvi_encoder(struct drm_connector *connector) >> +amdgpu_connector_dvi_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); >> @@ -1224,7 +1227,7 @@ static int amdgpu_connector_dp_get_modes(struct drm_connector *connector) >> { >> struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); >> struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv; >> - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); >> + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); >> int ret; >> >> if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || >> @@ -1363,7 +1366,7 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) >> struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); >> enum drm_connector_status ret = connector_status_disconnected; >> struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv; >> - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); >> + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); >> int r; >> >> if (!drm_kms_helper_is_poll_worker()) { >> @@ -1458,7 +1461,7 @@ static enum drm_mode_status amdgpu_connector_dp_mode_valid(struct drm_connector >> >> if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || >> (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { >> - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); >> + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); >> >> if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) >> return MODE_PANEL; >> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c >> index dbf2ccd0c744..b02ce39e65b7 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c >> +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c >> @@ -267,7 +267,8 @@ static int dce_virtual_early_init(void *handle) >> } >> >> static struct drm_encoder * >> -dce_virtual_encoder(struct drm_connector *connector) >> +dce_virtual_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> struct drm_encoder *encoder; >> 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 3e1c2a04d669..e56ed4e5818f 100644 >> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c >> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c >> @@ -2758,7 +2758,8 @@ static const struct drm_connector_funcs amdgpu_dm_connector_funcs = { >> .atomic_get_property = amdgpu_dm_connector_atomic_get_property >> }; >> >> -static struct drm_encoder *best_encoder(struct drm_connector *connector) >> +static struct drm_encoder *best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> struct drm_mode_object *obj; >> @@ -3304,7 +3305,7 @@ static void amdgpu_dm_get_native_mode(struct drm_connector *connector) >> struct drm_encoder *encoder; >> struct amdgpu_encoder *amdgpu_encoder; >> >> - encoder = helper->best_encoder(connector); >> + encoder = helper->best_encoder(connector, NULL); >> >> if (encoder == NULL) >> return; >> @@ -3438,7 +3439,7 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) >> struct drm_encoder *encoder; >> struct edid *edid = amdgpu_dm_connector->edid; >> >> - encoder = helper->best_encoder(connector); >> + encoder = helper->best_encoder(connector, NULL); >> amdgpu_dm_connector_ddc_get_modes(connector, edid); >> amdgpu_dm_connector_add_common_modes(encoder, connector); >> >> 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 4304d9e408b8..4544a1401caf 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 >> @@ -269,7 +269,8 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) >> return ret; >> } >> >> -static struct drm_encoder *dm_mst_best_encoder(struct drm_connector *connector) >> +static struct drm_encoder *dm_mst_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); >> >> @@ -302,7 +303,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector) >> const struct drm_connector_helper_funcs *connector_funcs = >> connector->base.helper_private; >> struct drm_encoder *enc_master = >> - connector_funcs->best_encoder(&connector->base); >> + connector_funcs->best_encoder(&connector->base, NULL); >> >> DRM_DEBUG_KMS("enc master is %p\n", enc_master); >> amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL); >> diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c >> index 036dff8a1f33..d5899aa41d37 100644 >> --- a/drivers/gpu/drm/ast/ast_mode.c >> +++ b/drivers/gpu/drm/ast/ast_mode.c >> @@ -709,7 +709,8 @@ static void ast_encoder_destroy(struct drm_encoder *encoder) >> } >> >> >> -static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connector) >> +static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> /* pick the encoder ids */ >> diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c >> index 233980a78591..dc80a238feef 100644 >> --- a/drivers/gpu/drm/bochs/bochs_kms.c >> +++ b/drivers/gpu/drm/bochs/bochs_kms.c >> @@ -208,7 +208,8 @@ static enum drm_mode_status bochs_connector_mode_valid(struct drm_connector *con >> } >> >> static struct drm_encoder * >> -bochs_connector_best_encoder(struct drm_connector *connector) >> +bochs_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> /* pick the encoder ids */ >> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c >> index 2bcbfadb6ac5..0706471c8c63 100644 >> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c >> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c >> @@ -1137,7 +1137,8 @@ static int analogix_dp_get_modes(struct drm_connector *connector) >> } >> >> static struct drm_encoder * >> -analogix_dp_best_encoder(struct drm_connector *connector) >> +analogix_dp_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct analogix_dp_device *dp = to_dp(connector); >> >> diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c >> index 0fd9cf27542c..7cd954226fe3 100644 >> --- a/drivers/gpu/drm/bridge/tc358767.c >> +++ b/drivers/gpu/drm/bridge/tc358767.c >> @@ -1155,7 +1155,8 @@ static void tc_connector_set_polling(struct tc_data *tc, >> } >> >> static struct drm_encoder * >> -tc_connector_best_encoder(struct drm_connector *connector) >> +tc_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct tc_data *tc = connector_to_tc(connector); >> >> diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c >> index b529f8c8e2a6..378ebc3f25e8 100644 >> --- a/drivers/gpu/drm/cirrus/cirrus_mode.c >> +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c >> @@ -451,8 +451,9 @@ static int cirrus_vga_get_modes(struct drm_connector *connector) >> return count; >> } >> >> -static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector >> - *connector) >> +static struct drm_encoder * >> +cirrus_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> /* pick the encoder ids */ >> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c >> index 232fa11a5e31..bd3aebbfd5b4 100644 >> --- a/drivers/gpu/drm/drm_atomic_helper.c >> +++ b/drivers/gpu/drm/drm_atomic_helper.c >> @@ -115,9 +115,11 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, >> if (funcs->atomic_best_encoder) >> new_encoder = funcs->atomic_best_encoder(connector, new_conn_state); >> else if (funcs->best_encoder) >> - new_encoder = funcs->best_encoder(connector); >> + new_encoder = funcs->best_encoder(connector, >> + new_conn_state->crtc); >> else >> - new_encoder = drm_atomic_helper_best_encoder(connector); >> + new_encoder = drm_atomic_helper_best_encoder(connector, >> + new_conn_state->crtc); >> >> if (new_encoder) { >> if (encoder_mask & (1 << drm_encoder_index(new_encoder))) { >> @@ -312,9 +314,11 @@ update_connector_routing(struct drm_atomic_state *state, >> new_encoder = funcs->atomic_best_encoder(connector, >> new_connector_state); >> else if (funcs->best_encoder) >> - new_encoder = funcs->best_encoder(connector); >> + new_encoder = funcs->best_encoder(connector, >> + new_connector_state->crtc); >> else >> - new_encoder = drm_atomic_helper_best_encoder(connector); >> + new_encoder = drm_atomic_helper_best_encoder(connector, >> + new_connector_state->crtc); >> >> if (!new_encoder) { >> DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n", >> @@ -3318,13 +3322,15 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip_target); >> * drm_atomic_helper_best_encoder - Helper for >> * &drm_connector_helper_funcs.best_encoder callback >> * @connector: Connector control structure >> + * @crtc: DRM crtc >> * >> * This is a &drm_connector_helper_funcs.best_encoder callback helper for >> * connectors that support exactly 1 encoder, statically determined at driver >> * init time. >> */ >> struct drm_encoder * >> -drm_atomic_helper_best_encoder(struct drm_connector *connector) >> +drm_atomic_helper_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> WARN_ON(connector->encoder_ids[1]); >> return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); >> diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c >> index 5a84c3bc915d..f9318fc11fb1 100644 >> --- a/drivers/gpu/drm/drm_crtc_helper.c >> +++ b/drivers/gpu/drm/drm_crtc_helper.c >> @@ -637,7 +637,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set, >> new_encoder = connector->encoder; >> for (ro = 0; ro < set->num_connectors; ro++) { >> if (set->connectors[ro] == connector) { >> - new_encoder = connector_funcs->best_encoder(connector); >> + new_encoder = connector_funcs->best_encoder(connector, >> + set->crtc); >> /* if we can't get an encoder for a connector >> we are setting now - then fail */ >> if (new_encoder == NULL) >> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c >> index cab14f253384..ce91ae12cccb 100644 >> --- a/drivers/gpu/drm/drm_fb_helper.c >> +++ b/drivers/gpu/drm/drm_fb_helper.c >> @@ -2331,9 +2331,8 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, >> int c, o; >> struct drm_connector *connector; >> const struct drm_connector_helper_funcs *connector_funcs; >> - struct drm_encoder *encoder; >> int my_score, best_score, score; >> - struct drm_fb_helper_crtc **crtcs, *crtc; >> + struct drm_fb_helper_crtc **crtcs; >> struct drm_fb_helper_connector *fb_helper_conn; >> >> if (n == fb_helper->connector_count) >> @@ -2362,28 +2361,32 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, >> >> connector_funcs = connector->helper_private; >> >> - /* >> - * If the DRM device implements atomic hooks and ->best_encoder() is >> - * NULL we fallback to the default drm_atomic_helper_best_encoder() >> - * helper. >> - */ >> - if (drm_drv_uses_atomic_modeset(fb_helper->dev) && >> - !connector_funcs->best_encoder) >> - encoder = drm_atomic_helper_best_encoder(connector); >> - else >> - encoder = connector_funcs->best_encoder(connector); >> - >> - if (!encoder) >> - goto out; >> - >> /* >> * select a crtc for this connector and then attempt to configure >> * remaining connectors >> */ >> for (c = 0; c < fb_helper->crtc_count; c++) { >> - crtc = &fb_helper->crtc_info[c]; >> + struct drm_encoder *encoder; >> + struct drm_fb_helper_crtc *crtc = &fb_helper->crtc_info[c]; >> >> - if ((encoder->possible_crtcs & (1 << c)) == 0) >> + /* >> + * If the DRM device implements atomic hooks and ->best_encoder() is >> + * NULL we fallback to the default drm_atomic_helper_best_encoder() >> + * helper. >> + */ >> + if (drm_drv_uses_atomic_modeset(fb_helper->dev) && >> + !connector_funcs->best_encoder) >> + encoder = drm_atomic_helper_best_encoder(connector, >> + crtc->mode_set.crtc); >> + else >> + encoder = connector_funcs->best_encoder(connector, >> + crtc->mode_set.crtc); >> + >> + if (!encoder) >> + continue; >> + >> + if ((encoder->possible_crtcs & >> + drm_crtc_mask(crtc->mode_set.crtc)) == 0) >> continue; >> >> for (o = 0; o < n; o++) >> @@ -2410,7 +2413,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, >> sizeof(struct drm_fb_helper_crtc *)); >> } >> } >> -out: >> + >> kfree(crtcs); >> return best_score; >> } >> diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c >> index c8f071c47daf..251b64653dc8 100644 >> --- a/drivers/gpu/drm/gma500/gma_display.c >> +++ b/drivers/gpu/drm/gma500/gma_display.c >> @@ -652,7 +652,8 @@ void gma_encoder_destroy(struct drm_encoder *encoder) >> } >> >> /* Currently there is only a 1:1 mapping of encoders and connectors */ >> -struct drm_encoder *gma_best_encoder(struct drm_connector *connector) >> +struct drm_encoder *gma_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct gma_encoder *gma_encoder = gma_attached_encoder(connector); >> >> diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c >> index fe020926ea4f..9e5b059a9e5b 100644 >> --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c >> +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c >> @@ -377,8 +377,9 @@ static enum drm_mode_status mdfld_dsi_connector_mode_valid(struct drm_connector >> return MODE_OK; >> } >> >> -static struct drm_encoder *mdfld_dsi_connector_best_encoder( >> - struct drm_connector *connector) >> +static struct drm_encoder * >> +mdfld_dsi_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct mdfld_dsi_connector *dsi_connector = >> mdfld_dsi_connector(connector); >> diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h >> index e05e5399af2d..e903525b9d30 100644 >> --- a/drivers/gpu/drm/gma500/psb_intel_drv.h >> +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h >> @@ -230,7 +230,8 @@ extern void oaktrail_lvds_i2c_init(struct drm_encoder *encoder); >> extern void mid_dsi_init(struct drm_device *dev, >> struct psb_intel_mode_device *mode_dev, int dsi_num); >> >> -extern struct drm_encoder *gma_best_encoder(struct drm_connector *connector); >> +extern struct drm_encoder *gma_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc); >> extern void gma_connector_attach_encoder(struct gma_connector *connector, >> struct gma_encoder *encoder); >> >> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c >> index d2f4749ebf8d..89a0104f9855 100644 >> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c >> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c >> @@ -34,7 +34,8 @@ static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *con >> } >> >> static struct drm_encoder * >> -hibmc_connector_best_encoder(struct drm_connector *connector) >> +hibmc_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); >> } >> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c >> index 0038c976536a..422347d977b4 100644 >> --- a/drivers/gpu/drm/i2c/tda998x_drv.c >> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c >> @@ -1267,7 +1267,8 @@ static enum drm_mode_status tda998x_connector_mode_valid(struct drm_connector *c >> } >> >> static struct drm_encoder * >> -tda998x_connector_best_encoder(struct drm_connector *connector) >> +tda998x_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct tda998x_priv *priv = conn_to_tda998x_priv(connector); >> >> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c >> index 5890500a3a8b..d9119d516579 100644 >> --- a/drivers/gpu/drm/i915/intel_dp_mst.c >> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c >> @@ -403,20 +403,23 @@ static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *c >> return &intel_dp->mst_encoders[crtc->pipe]->base.base; >> } >> >> -static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector) >> +static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *_crtc) >> { >> struct intel_connector *intel_connector = to_intel_connector(connector); >> struct intel_dp *intel_dp = intel_connector->mst_port; >> + struct intel_crtc *crtc = to_intel_crtc(_crtc); >> + >> if (!intel_dp) >> return NULL; >> - return &intel_dp->mst_encoders[0]->base.base; >> + return &intel_dp->mst_encoders[crtc->pipe]->base.base; >> } >> >> static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { >> .get_modes = intel_dp_mst_get_modes, >> .mode_valid = intel_dp_mst_mode_valid, >> .atomic_best_encoder = intel_mst_atomic_best_encoder, >> - .best_encoder = intel_mst_best_encoder, >> + .best_encoder = intel_mst_best_encoder, /* only for fb_helper */ >> .atomic_check = intel_dp_mst_atomic_check, >> }; >> >> diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c >> index 56dd7a9a8e25..f1523cccc090 100644 >> --- a/drivers/gpu/drm/imx/imx-ldb.c >> +++ b/drivers/gpu/drm/imx/imx-ldb.c >> @@ -163,8 +163,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) >> return num_modes; >> } >> >> -static struct drm_encoder *imx_ldb_connector_best_encoder( >> - struct drm_connector *connector) >> +static struct drm_encoder * >> +imx_ldb_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); >> >> diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c >> index bc27c2699464..71f49ac835ec 100644 >> --- a/drivers/gpu/drm/imx/imx-tve.c >> +++ b/drivers/gpu/drm/imx/imx-tve.c >> @@ -265,8 +265,9 @@ static int imx_tve_connector_mode_valid(struct drm_connector *connector, >> return MODE_BAD; >> } >> >> -static struct drm_encoder *imx_tve_connector_best_encoder( >> - struct drm_connector *connector) >> +static struct drm_encoder * >> +imx_tve_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct imx_tve *tve = con_to_tve(connector); >> >> diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c >> index aedecda9728a..438f95dee73e 100644 >> --- a/drivers/gpu/drm/imx/parallel-display.c >> +++ b/drivers/gpu/drm/imx/parallel-display.c >> @@ -89,8 +89,9 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) >> return num_modes; >> } >> >> -static struct drm_encoder *imx_pd_connector_best_encoder( >> - struct drm_connector *connector) >> +static struct drm_encoder * >> +imx_pd_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct imx_parallel_display *imxpd = con_to_imxpd(connector); >> >> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c >> index 59a11026dceb..c0578779fb19 100644 >> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c >> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c >> @@ -1253,7 +1253,8 @@ static int mtk_hdmi_conn_mode_valid(struct drm_connector *conn, >> return drm_mode_validate_size(mode, 0x1fff, 0x1fff); >> } >> >> -static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn) >> +static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn, >> + struct drm_crtc *crtc) >> { >> struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); >> >> diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c >> index 8918539a19aa..4059f04030ee 100644 >> --- a/drivers/gpu/drm/mgag200/mgag200_mode.c >> +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c >> @@ -1664,8 +1664,9 @@ static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector, >> return MODE_OK; >> } >> >> -static struct drm_encoder *mga_connector_best_encoder(struct drm_connector >> - *connector) >> +static struct drm_encoder * >> +mga_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> /* pick the encoder ids */ >> diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c >> index 4cb1cb68878b..8cbede64819e 100644 >> --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c >> +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c >> @@ -426,7 +426,8 @@ static int dsi_mgr_connector_mode_valid(struct drm_connector *connector, >> } >> >> static struct drm_encoder * >> -dsi_mgr_connector_best_encoder(struct drm_connector *connector) >> +dsi_mgr_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int id = dsi_mgr_connector_get_id(connector); >> struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); >> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c >> index b83465ae7c1b..a9bacb0a1e16 100644 >> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c >> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c >> @@ -826,7 +826,8 @@ nv50_mstc_atomic_best_encoder(struct drm_connector *connector, >> } >> >> static struct drm_encoder * >> -nv50_mstc_best_encoder(struct drm_connector *connector) >> +nv50_mstc_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct nv50_mstc *mstc = nv50_mstc(connector); >> if (mstc->port) { >> diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c >> index 7b557c354307..ee4bf532b932 100644 >> --- a/drivers/gpu/drm/nouveau/nouveau_connector.c >> +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c >> @@ -1063,7 +1063,8 @@ nouveau_connector_mode_valid(struct drm_connector *connector, >> } >> >> static struct drm_encoder * >> -nouveau_connector_best_encoder(struct drm_connector *connector) >> +nouveau_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct nouveau_connector *nv_connector = nouveau_connector(connector); >> >> diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c >> index 768207fbbae3..fa5c84f35531 100644 >> --- a/drivers/gpu/drm/qxl/qxl_display.c >> +++ b/drivers/gpu/drm/qxl/qxl_display.c >> @@ -978,7 +978,8 @@ static enum drm_mode_status qxl_conn_mode_valid(struct drm_connector *connector, >> return MODE_BAD; >> } >> >> -static struct drm_encoder *qxl_best_encoder(struct drm_connector *connector) >> +static struct drm_encoder *qxl_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct qxl_output *qxl_output = >> drm_connector_to_qxl_output(connector); >> diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c >> index 2aea2bdff99b..8bf7298dccb3 100644 >> --- a/drivers/gpu/drm/radeon/radeon_connectors.c >> +++ b/drivers/gpu/drm/radeon/radeon_connectors.c >> @@ -158,7 +158,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) >> else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { >> const struct drm_connector_helper_funcs *connector_funcs = >> connector->helper_private; >> - struct drm_encoder *encoder = connector_funcs->best_encoder(connector); >> + struct drm_encoder *encoder = connector_funcs->best_encoder(connector, NULL); >> struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); >> struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; >> >> @@ -250,7 +250,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c >> bool connected; >> int i; >> >> - best_encoder = connector_funcs->best_encoder(connector); >> + best_encoder = connector_funcs->best_encoder(connector, NULL); >> >> for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { >> if (connector->encoder_ids[i] == 0) >> @@ -391,7 +391,8 @@ static int radeon_ddc_get_modes(struct drm_connector *connector) >> return 0; >> } >> >> -static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) >> +static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> /* pick the encoder ids */ >> @@ -402,7 +403,7 @@ static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *conn >> >> static void radeon_get_native_mode(struct drm_connector *connector) >> { >> - struct drm_encoder *encoder = radeon_best_single_encoder(connector); >> + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); >> struct radeon_encoder *radeon_encoder; >> >> if (encoder == NULL) >> @@ -728,7 +729,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct >> radeon_encoder = to_radeon_encoder(connector->encoder); >> else { >> const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; >> - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); >> + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); >> } >> >> switch (val) { >> @@ -755,7 +756,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct >> radeon_encoder = to_radeon_encoder(connector->encoder); >> else { >> const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; >> - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); >> + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); >> } >> >> if (radeon_encoder->output_csc == val) >> @@ -824,7 +825,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) >> radeon_connector_get_edid(connector); >> ret = radeon_ddc_get_modes(connector); >> if (ret > 0) { >> - encoder = radeon_best_single_encoder(connector); >> + encoder = radeon_best_single_encoder(connector, NULL); >> if (encoder) { >> radeon_fixup_lvds_native_mode(encoder, connector); >> /* add scaled modes */ >> @@ -833,7 +834,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) >> return ret; >> } >> >> - encoder = radeon_best_single_encoder(connector); >> + encoder = radeon_best_single_encoder(connector, NULL); >> if (!encoder) >> return 0; >> >> @@ -855,7 +856,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) >> static enum drm_mode_status radeon_lvds_mode_valid(struct drm_connector *connector, >> struct drm_display_mode *mode) >> { >> - struct drm_encoder *encoder = radeon_best_single_encoder(connector); >> + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); >> >> if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) >> return MODE_PANEL; >> @@ -888,7 +889,7 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) >> struct drm_device *dev = connector->dev; >> struct radeon_device *rdev = dev->dev_private; >> struct radeon_connector *radeon_connector = to_radeon_connector(connector); >> - struct drm_encoder *encoder = radeon_best_single_encoder(connector); >> + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); >> enum drm_connector_status ret = connector_status_disconnected; >> int r; >> >> @@ -965,7 +966,7 @@ static int radeon_lvds_set_property(struct drm_connector *connector, >> radeon_encoder = to_radeon_encoder(connector->encoder); >> else { >> const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; >> - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); >> + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); >> } >> >> switch (value) { >> @@ -1044,7 +1045,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) >> return connector_status_disconnected; >> } >> >> - encoder = radeon_best_single_encoder(connector); >> + encoder = radeon_best_single_encoder(connector, NULL); >> if (!encoder) >> ret = connector_status_disconnected; >> >> @@ -1139,7 +1140,7 @@ static int radeon_tv_get_modes(struct drm_connector *connector) >> struct drm_display_mode *tv_mode; >> struct drm_encoder *encoder; >> >> - encoder = radeon_best_single_encoder(connector); >> + encoder = radeon_best_single_encoder(connector, NULL); >> if (!encoder) >> return 0; >> >> @@ -1182,7 +1183,7 @@ radeon_tv_detect(struct drm_connector *connector, bool force) >> return connector_status_disconnected; >> } >> >> - encoder = radeon_best_single_encoder(connector); >> + encoder = radeon_best_single_encoder(connector, NULL); >> if (!encoder) >> ret = connector_status_disconnected; >> else { >> @@ -1439,7 +1440,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) >> const struct drm_connector_helper_funcs *connector_funcs = >> connector->helper_private; >> >> - encoder = connector_funcs->best_encoder(connector); >> + encoder = connector_funcs->best_encoder(connector, NULL); >> if (encoder && (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)) { >> radeon_connector_get_edid(connector); >> radeon_audio_detect(connector, encoder, ret); >> @@ -1456,7 +1457,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) >> } >> >> /* okay need to be smart in here about which encoder to pick */ >> -static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) >> +static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> struct radeon_connector *radeon_connector = to_radeon_connector(connector); >> @@ -1556,7 +1558,7 @@ static int radeon_dp_get_modes(struct drm_connector *connector) >> { >> struct radeon_connector *radeon_connector = to_radeon_connector(connector); >> struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; >> - struct drm_encoder *encoder = radeon_best_single_encoder(connector); >> + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); >> int ret; >> >> if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || >> @@ -1695,7 +1697,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) >> struct radeon_connector *radeon_connector = to_radeon_connector(connector); >> enum drm_connector_status ret = connector_status_disconnected; >> struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; >> - struct drm_encoder *encoder = radeon_best_single_encoder(connector); >> + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); >> int r; >> >> if (radeon_dig_connector->is_mst) >> @@ -1812,7 +1814,7 @@ static enum drm_mode_status radeon_dp_mode_valid(struct drm_connector *connector >> >> if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || >> (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { >> - struct drm_encoder *encoder = radeon_best_single_encoder(connector); >> + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); >> >> if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) >> return MODE_PANEL; >> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c >> index cd8a3ee16649..fd5a0dae0e1f 100644 >> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c >> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c >> @@ -224,7 +224,8 @@ radeon_dp_mst_mode_valid(struct drm_connector *connector, >> } >> >> static struct >> -drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector) >> +drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct radeon_connector *radeon_connector = to_radeon_connector(connector); >> >> @@ -613,7 +614,7 @@ radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector) >> struct radeon_encoder_mst *mst_enc; >> struct drm_encoder *encoder; >> const struct drm_connector_helper_funcs *connector_funcs = connector->base.helper_private; >> - struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base); >> + struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base, NULL); >> >> DRM_DEBUG_KMS("enc master is %p\n", enc_master); >> radeon_encoder = kzalloc(sizeof(*radeon_encoder), GFP_KERNEL); >> diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c >> index e7738939a86d..cdc991d5c28e 100644 >> --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c >> +++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c >> @@ -668,7 +668,8 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector) >> } >> >> static struct drm_encoder * >> -shmob_drm_connector_best_encoder(struct drm_connector *connector) >> +shmob_drm_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct shmob_drm_connector *scon = to_shmob_connector(connector); >> >> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c >> index d616d64a6725..197962eca1af 100644 >> --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c >> +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c >> @@ -178,8 +178,9 @@ static int panel_connector_mode_valid(struct drm_connector *connector, >> return tilcdc_crtc_mode_valid(priv->crtc, mode); >> } >> >> -static struct drm_encoder *panel_connector_best_encoder( >> - struct drm_connector *connector) >> +static struct drm_encoder * >> +panel_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct panel_connector *panel_connector = to_panel_connector(connector); >> return panel_connector->encoder; >> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c >> index c45cabb38db0..0ef8221c5334 100644 >> --- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c >> +++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c >> @@ -191,8 +191,9 @@ static int tfp410_connector_mode_valid(struct drm_connector *connector, >> return tilcdc_crtc_mode_valid(priv->crtc, mode); >> } >> >> -static struct drm_encoder *tfp410_connector_best_encoder( >> - struct drm_connector *connector) >> +static struct drm_encoder * >> +tfp410_connector_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector); >> return tfp410_connector->encoder; >> diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c >> index 09dc585aa46f..803ae6515892 100644 >> --- a/drivers/gpu/drm/udl/udl_connector.c >> +++ b/drivers/gpu/drm/udl/udl_connector.c >> @@ -145,7 +145,8 @@ udl_detect(struct drm_connector *connector, bool force) >> } >> >> static struct drm_encoder* >> -udl_best_single_encoder(struct drm_connector *connector) >> +udl_best_single_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> return drm_encoder_find(connector->dev, NULL, enc_id); >> diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c >> index b265fe924556..bf0e93705e1c 100644 >> --- a/drivers/staging/vboxvideo/vbox_mode.c >> +++ b/drivers/staging/vboxvideo/vbox_mode.c >> @@ -370,8 +370,9 @@ static void vbox_encoder_destroy(struct drm_encoder *encoder) >> kfree(encoder); >> } >> >> -static struct drm_encoder *vbox_best_single_encoder(struct drm_connector >> - *connector) >> +static struct drm_encoder * >> +vbox_best_single_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc) >> { >> int enc_id = connector->encoder_ids[0]; >> >> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h >> index 26aaba58d6ce..e0f00d43ed63 100644 >> --- a/include/drm/drm_atomic_helper.h >> +++ b/include/drm/drm_atomic_helper.h >> @@ -143,7 +143,8 @@ int drm_atomic_helper_page_flip_target( >> uint32_t target, >> struct drm_modeset_acquire_ctx *ctx); >> struct drm_encoder * >> -drm_atomic_helper_best_encoder(struct drm_connector *connector); >> +drm_atomic_helper_best_encoder(struct drm_connector *connector, >> + struct drm_crtc *crtc); >> >> /* default implementations for state handling */ >> void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); >> diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h >> index 35e2a3a79fc5..a9b3a2c50877 100644 >> --- a/include/drm/drm_modeset_helper_vtables.h >> +++ b/include/drm/drm_modeset_helper_vtables.h >> @@ -885,7 +885,8 @@ struct drm_connector_helper_funcs { >> /** >> * @best_encoder: >> * >> - * This function should select the best encoder for the given connector. >> + * This function should select the best encoder for the given connector >> + * and crtc. For some driver internal use crtc may be NULL. >> * >> * This function is used by both the atomic helpers (in the >> * drm_atomic_helper_check_modeset() function) and in the legacy CRTC >> @@ -911,7 +912,8 @@ struct drm_connector_helper_funcs { >> * will ensure that encoders aren't used twice, drivers should not check >> * for this. >> */ >> - struct drm_encoder *(*best_encoder)(struct drm_connector *connector); >> + struct drm_encoder *(*best_encoder)(struct drm_connector *connector, >> + struct drm_crtc *crtc); >> >> /** >> * @atomic_best_encoder: >> > _______________________________________________ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx >
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index 8e66851eb427..3dfa50ec2589 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -135,7 +135,8 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) else { const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - struct drm_encoder *encoder = connector_funcs->best_encoder(connector); + struct drm_encoder *encoder = connector_funcs->best_encoder(connector, + NULL); struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder); struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv; @@ -218,7 +219,7 @@ amdgpu_connector_update_scratch_regs(struct drm_connector *connector, bool connected; int i; - best_encoder = connector_funcs->best_encoder(connector); + best_encoder = connector_funcs->best_encoder(connector, NULL); for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { if (connector->encoder_ids[i] == 0) @@ -358,7 +359,8 @@ static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) } static struct drm_encoder * -amdgpu_connector_best_single_encoder(struct drm_connector *connector) +amdgpu_connector_best_single_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; @@ -370,7 +372,7 @@ amdgpu_connector_best_single_encoder(struct drm_connector *connector) static void amdgpu_get_native_mode(struct drm_connector *connector) { - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); struct amdgpu_encoder *amdgpu_encoder; if (encoder == NULL) @@ -593,7 +595,7 @@ static int amdgpu_connector_set_property(struct drm_connector *connector, amdgpu_encoder = to_amdgpu_encoder(connector->encoder); } else { const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector)); + amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector, NULL)); } switch (val) { @@ -663,7 +665,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) amdgpu_connector_get_edid(connector); ret = amdgpu_connector_ddc_get_modes(connector); if (ret > 0) { - encoder = amdgpu_connector_best_single_encoder(connector); + encoder = amdgpu_connector_best_single_encoder(connector, NULL); if (encoder) { amdgpu_connector_fixup_lcd_native_mode(encoder, connector); /* add scaled modes */ @@ -672,7 +674,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) return ret; } - encoder = amdgpu_connector_best_single_encoder(connector); + encoder = amdgpu_connector_best_single_encoder(connector, NULL); if (!encoder) return 0; @@ -694,7 +696,7 @@ static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector) static enum drm_mode_status amdgpu_connector_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) return MODE_PANEL; @@ -725,7 +727,7 @@ static enum drm_connector_status amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force) { struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); enum drm_connector_status ret = connector_status_disconnected; int r; @@ -798,7 +800,7 @@ static int amdgpu_connector_set_lcd_property(struct drm_connector *connector, amdgpu_encoder = to_amdgpu_encoder(connector->encoder); else { const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector)); + amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector, NULL)); } switch (value) { @@ -873,7 +875,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) return connector_status_disconnected; } - encoder = amdgpu_connector_best_single_encoder(connector); + encoder = amdgpu_connector_best_single_encoder(connector, NULL); if (!encoder) ret = connector_status_disconnected; @@ -1130,7 +1132,8 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) /* okay need to be smart in here about which encoder to pick */ static struct drm_encoder * -amdgpu_connector_dvi_encoder(struct drm_connector *connector) +amdgpu_connector_dvi_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); @@ -1224,7 +1227,7 @@ static int amdgpu_connector_dp_get_modes(struct drm_connector *connector) { struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv; - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); int ret; if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || @@ -1363,7 +1366,7 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); enum drm_connector_status ret = connector_status_disconnected; struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv; - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); int r; if (!drm_kms_helper_is_poll_worker()) { @@ -1458,7 +1461,7 @@ static enum drm_mode_status amdgpu_connector_dp_mode_valid(struct drm_connector if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { - struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); + struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector, NULL); if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) return MODE_PANEL; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c index dbf2ccd0c744..b02ce39e65b7 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c @@ -267,7 +267,8 @@ static int dce_virtual_early_init(void *handle) } static struct drm_encoder * -dce_virtual_encoder(struct drm_connector *connector) +dce_virtual_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; struct drm_encoder *encoder; 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 3e1c2a04d669..e56ed4e5818f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2758,7 +2758,8 @@ static const struct drm_connector_funcs amdgpu_dm_connector_funcs = { .atomic_get_property = amdgpu_dm_connector_atomic_get_property }; -static struct drm_encoder *best_encoder(struct drm_connector *connector) +static struct drm_encoder *best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; struct drm_mode_object *obj; @@ -3304,7 +3305,7 @@ static void amdgpu_dm_get_native_mode(struct drm_connector *connector) struct drm_encoder *encoder; struct amdgpu_encoder *amdgpu_encoder; - encoder = helper->best_encoder(connector); + encoder = helper->best_encoder(connector, NULL); if (encoder == NULL) return; @@ -3438,7 +3439,7 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) struct drm_encoder *encoder; struct edid *edid = amdgpu_dm_connector->edid; - encoder = helper->best_encoder(connector); + encoder = helper->best_encoder(connector, NULL); amdgpu_dm_connector_ddc_get_modes(connector, edid); amdgpu_dm_connector_add_common_modes(encoder, connector); 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 4304d9e408b8..4544a1401caf 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 @@ -269,7 +269,8 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) return ret; } -static struct drm_encoder *dm_mst_best_encoder(struct drm_connector *connector) +static struct drm_encoder *dm_mst_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); @@ -302,7 +303,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector) const struct drm_connector_helper_funcs *connector_funcs = connector->base.helper_private; struct drm_encoder *enc_master = - connector_funcs->best_encoder(&connector->base); + connector_funcs->best_encoder(&connector->base, NULL); DRM_DEBUG_KMS("enc master is %p\n", enc_master); amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL); diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 036dff8a1f33..d5899aa41d37 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -709,7 +709,8 @@ static void ast_encoder_destroy(struct drm_encoder *encoder) } -static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connector) +static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; /* pick the encoder ids */ diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 233980a78591..dc80a238feef 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -208,7 +208,8 @@ static enum drm_mode_status bochs_connector_mode_valid(struct drm_connector *con } static struct drm_encoder * -bochs_connector_best_encoder(struct drm_connector *connector) +bochs_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; /* pick the encoder ids */ diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 2bcbfadb6ac5..0706471c8c63 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1137,7 +1137,8 @@ static int analogix_dp_get_modes(struct drm_connector *connector) } static struct drm_encoder * -analogix_dp_best_encoder(struct drm_connector *connector) +analogix_dp_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct analogix_dp_device *dp = to_dp(connector); diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 0fd9cf27542c..7cd954226fe3 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -1155,7 +1155,8 @@ static void tc_connector_set_polling(struct tc_data *tc, } static struct drm_encoder * -tc_connector_best_encoder(struct drm_connector *connector) +tc_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct tc_data *tc = connector_to_tc(connector); diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c index b529f8c8e2a6..378ebc3f25e8 100644 --- a/drivers/gpu/drm/cirrus/cirrus_mode.c +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c @@ -451,8 +451,9 @@ static int cirrus_vga_get_modes(struct drm_connector *connector) return count; } -static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector - *connector) +static struct drm_encoder * +cirrus_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; /* pick the encoder ids */ diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 232fa11a5e31..bd3aebbfd5b4 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -115,9 +115,11 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, if (funcs->atomic_best_encoder) new_encoder = funcs->atomic_best_encoder(connector, new_conn_state); else if (funcs->best_encoder) - new_encoder = funcs->best_encoder(connector); + new_encoder = funcs->best_encoder(connector, + new_conn_state->crtc); else - new_encoder = drm_atomic_helper_best_encoder(connector); + new_encoder = drm_atomic_helper_best_encoder(connector, + new_conn_state->crtc); if (new_encoder) { if (encoder_mask & (1 << drm_encoder_index(new_encoder))) { @@ -312,9 +314,11 @@ update_connector_routing(struct drm_atomic_state *state, new_encoder = funcs->atomic_best_encoder(connector, new_connector_state); else if (funcs->best_encoder) - new_encoder = funcs->best_encoder(connector); + new_encoder = funcs->best_encoder(connector, + new_connector_state->crtc); else - new_encoder = drm_atomic_helper_best_encoder(connector); + new_encoder = drm_atomic_helper_best_encoder(connector, + new_connector_state->crtc); if (!new_encoder) { DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n", @@ -3318,13 +3322,15 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip_target); * drm_atomic_helper_best_encoder - Helper for * &drm_connector_helper_funcs.best_encoder callback * @connector: Connector control structure + * @crtc: DRM crtc * * This is a &drm_connector_helper_funcs.best_encoder callback helper for * connectors that support exactly 1 encoder, statically determined at driver * init time. */ struct drm_encoder * -drm_atomic_helper_best_encoder(struct drm_connector *connector) +drm_atomic_helper_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { WARN_ON(connector->encoder_ids[1]); return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 5a84c3bc915d..f9318fc11fb1 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -637,7 +637,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set, new_encoder = connector->encoder; for (ro = 0; ro < set->num_connectors; ro++) { if (set->connectors[ro] == connector) { - new_encoder = connector_funcs->best_encoder(connector); + new_encoder = connector_funcs->best_encoder(connector, + set->crtc); /* if we can't get an encoder for a connector we are setting now - then fail */ if (new_encoder == NULL) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index cab14f253384..ce91ae12cccb 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2331,9 +2331,8 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, int c, o; struct drm_connector *connector; const struct drm_connector_helper_funcs *connector_funcs; - struct drm_encoder *encoder; int my_score, best_score, score; - struct drm_fb_helper_crtc **crtcs, *crtc; + struct drm_fb_helper_crtc **crtcs; struct drm_fb_helper_connector *fb_helper_conn; if (n == fb_helper->connector_count) @@ -2362,28 +2361,32 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, connector_funcs = connector->helper_private; - /* - * If the DRM device implements atomic hooks and ->best_encoder() is - * NULL we fallback to the default drm_atomic_helper_best_encoder() - * helper. - */ - if (drm_drv_uses_atomic_modeset(fb_helper->dev) && - !connector_funcs->best_encoder) - encoder = drm_atomic_helper_best_encoder(connector); - else - encoder = connector_funcs->best_encoder(connector); - - if (!encoder) - goto out; - /* * select a crtc for this connector and then attempt to configure * remaining connectors */ for (c = 0; c < fb_helper->crtc_count; c++) { - crtc = &fb_helper->crtc_info[c]; + struct drm_encoder *encoder; + struct drm_fb_helper_crtc *crtc = &fb_helper->crtc_info[c]; - if ((encoder->possible_crtcs & (1 << c)) == 0) + /* + * If the DRM device implements atomic hooks and ->best_encoder() is + * NULL we fallback to the default drm_atomic_helper_best_encoder() + * helper. + */ + if (drm_drv_uses_atomic_modeset(fb_helper->dev) && + !connector_funcs->best_encoder) + encoder = drm_atomic_helper_best_encoder(connector, + crtc->mode_set.crtc); + else + encoder = connector_funcs->best_encoder(connector, + crtc->mode_set.crtc); + + if (!encoder) + continue; + + if ((encoder->possible_crtcs & + drm_crtc_mask(crtc->mode_set.crtc)) == 0) continue; for (o = 0; o < n; o++) @@ -2410,7 +2413,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, sizeof(struct drm_fb_helper_crtc *)); } } -out: + kfree(crtcs); return best_score; } diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index c8f071c47daf..251b64653dc8 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -652,7 +652,8 @@ void gma_encoder_destroy(struct drm_encoder *encoder) } /* Currently there is only a 1:1 mapping of encoders and connectors */ -struct drm_encoder *gma_best_encoder(struct drm_connector *connector) +struct drm_encoder *gma_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct gma_encoder *gma_encoder = gma_attached_encoder(connector); diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c index fe020926ea4f..9e5b059a9e5b 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c @@ -377,8 +377,9 @@ static enum drm_mode_status mdfld_dsi_connector_mode_valid(struct drm_connector return MODE_OK; } -static struct drm_encoder *mdfld_dsi_connector_best_encoder( - struct drm_connector *connector) +static struct drm_encoder * +mdfld_dsi_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct mdfld_dsi_connector *dsi_connector = mdfld_dsi_connector(connector); diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h index e05e5399af2d..e903525b9d30 100644 --- a/drivers/gpu/drm/gma500/psb_intel_drv.h +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h @@ -230,7 +230,8 @@ extern void oaktrail_lvds_i2c_init(struct drm_encoder *encoder); extern void mid_dsi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int dsi_num); -extern struct drm_encoder *gma_best_encoder(struct drm_connector *connector); +extern struct drm_encoder *gma_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc); extern void gma_connector_attach_encoder(struct gma_connector *connector, struct gma_encoder *encoder); diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index d2f4749ebf8d..89a0104f9855 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -34,7 +34,8 @@ static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *con } static struct drm_encoder * -hibmc_connector_best_encoder(struct drm_connector *connector) +hibmc_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); } diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 0038c976536a..422347d977b4 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1267,7 +1267,8 @@ static enum drm_mode_status tda998x_connector_mode_valid(struct drm_connector *c } static struct drm_encoder * -tda998x_connector_best_encoder(struct drm_connector *connector) +tda998x_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct tda998x_priv *priv = conn_to_tda998x_priv(connector); diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 5890500a3a8b..d9119d516579 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -403,20 +403,23 @@ static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *c return &intel_dp->mst_encoders[crtc->pipe]->base.base; } -static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector) +static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector, + struct drm_crtc *_crtc) { struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_dp *intel_dp = intel_connector->mst_port; + struct intel_crtc *crtc = to_intel_crtc(_crtc); + if (!intel_dp) return NULL; - return &intel_dp->mst_encoders[0]->base.base; + return &intel_dp->mst_encoders[crtc->pipe]->base.base; } static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { .get_modes = intel_dp_mst_get_modes, .mode_valid = intel_dp_mst_mode_valid, .atomic_best_encoder = intel_mst_atomic_best_encoder, - .best_encoder = intel_mst_best_encoder, + .best_encoder = intel_mst_best_encoder, /* only for fb_helper */ .atomic_check = intel_dp_mst_atomic_check, }; diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 56dd7a9a8e25..f1523cccc090 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -163,8 +163,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) return num_modes; } -static struct drm_encoder *imx_ldb_connector_best_encoder( - struct drm_connector *connector) +static struct drm_encoder * +imx_ldb_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index bc27c2699464..71f49ac835ec 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -265,8 +265,9 @@ static int imx_tve_connector_mode_valid(struct drm_connector *connector, return MODE_BAD; } -static struct drm_encoder *imx_tve_connector_best_encoder( - struct drm_connector *connector) +static struct drm_encoder * +imx_tve_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct imx_tve *tve = con_to_tve(connector); diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index aedecda9728a..438f95dee73e 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -89,8 +89,9 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) return num_modes; } -static struct drm_encoder *imx_pd_connector_best_encoder( - struct drm_connector *connector) +static struct drm_encoder * +imx_pd_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct imx_parallel_display *imxpd = con_to_imxpd(connector); diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 59a11026dceb..c0578779fb19 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1253,7 +1253,8 @@ static int mtk_hdmi_conn_mode_valid(struct drm_connector *conn, return drm_mode_validate_size(mode, 0x1fff, 0x1fff); } -static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn) +static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn, + struct drm_crtc *crtc) { struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 8918539a19aa..4059f04030ee 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1664,8 +1664,9 @@ static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector, return MODE_OK; } -static struct drm_encoder *mga_connector_best_encoder(struct drm_connector - *connector) +static struct drm_encoder * +mga_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; /* pick the encoder ids */ diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 4cb1cb68878b..8cbede64819e 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -426,7 +426,8 @@ static int dsi_mgr_connector_mode_valid(struct drm_connector *connector, } static struct drm_encoder * -dsi_mgr_connector_best_encoder(struct drm_connector *connector) +dsi_mgr_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int id = dsi_mgr_connector_get_id(connector); struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index b83465ae7c1b..a9bacb0a1e16 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -826,7 +826,8 @@ nv50_mstc_atomic_best_encoder(struct drm_connector *connector, } static struct drm_encoder * -nv50_mstc_best_encoder(struct drm_connector *connector) +nv50_mstc_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct nv50_mstc *mstc = nv50_mstc(connector); if (mstc->port) { diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 7b557c354307..ee4bf532b932 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1063,7 +1063,8 @@ nouveau_connector_mode_valid(struct drm_connector *connector, } static struct drm_encoder * -nouveau_connector_best_encoder(struct drm_connector *connector) +nouveau_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct nouveau_connector *nv_connector = nouveau_connector(connector); diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 768207fbbae3..fa5c84f35531 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -978,7 +978,8 @@ static enum drm_mode_status qxl_conn_mode_valid(struct drm_connector *connector, return MODE_BAD; } -static struct drm_encoder *qxl_best_encoder(struct drm_connector *connector) +static struct drm_encoder *qxl_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct qxl_output *qxl_output = drm_connector_to_qxl_output(connector); diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2aea2bdff99b..8bf7298dccb3 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -158,7 +158,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - struct drm_encoder *encoder = connector_funcs->best_encoder(connector); + struct drm_encoder *encoder = connector_funcs->best_encoder(connector, NULL); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; @@ -250,7 +250,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c bool connected; int i; - best_encoder = connector_funcs->best_encoder(connector); + best_encoder = connector_funcs->best_encoder(connector, NULL); for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { if (connector->encoder_ids[i] == 0) @@ -391,7 +391,8 @@ static int radeon_ddc_get_modes(struct drm_connector *connector) return 0; } -static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) +static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; /* pick the encoder ids */ @@ -402,7 +403,7 @@ static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *conn static void radeon_get_native_mode(struct drm_connector *connector) { - struct drm_encoder *encoder = radeon_best_single_encoder(connector); + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); struct radeon_encoder *radeon_encoder; if (encoder == NULL) @@ -728,7 +729,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct radeon_encoder = to_radeon_encoder(connector->encoder); else { const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); } switch (val) { @@ -755,7 +756,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct radeon_encoder = to_radeon_encoder(connector->encoder); else { const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); } if (radeon_encoder->output_csc == val) @@ -824,7 +825,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) radeon_connector_get_edid(connector); ret = radeon_ddc_get_modes(connector); if (ret > 0) { - encoder = radeon_best_single_encoder(connector); + encoder = radeon_best_single_encoder(connector, NULL); if (encoder) { radeon_fixup_lvds_native_mode(encoder, connector); /* add scaled modes */ @@ -833,7 +834,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) return ret; } - encoder = radeon_best_single_encoder(connector); + encoder = radeon_best_single_encoder(connector, NULL); if (!encoder) return 0; @@ -855,7 +856,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) static enum drm_mode_status radeon_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct drm_encoder *encoder = radeon_best_single_encoder(connector); + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) return MODE_PANEL; @@ -888,7 +889,7 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) struct drm_device *dev = connector->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct drm_encoder *encoder = radeon_best_single_encoder(connector); + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); enum drm_connector_status ret = connector_status_disconnected; int r; @@ -965,7 +966,7 @@ static int radeon_lvds_set_property(struct drm_connector *connector, radeon_encoder = to_radeon_encoder(connector->encoder); else { const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector, NULL)); } switch (value) { @@ -1044,7 +1045,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) return connector_status_disconnected; } - encoder = radeon_best_single_encoder(connector); + encoder = radeon_best_single_encoder(connector, NULL); if (!encoder) ret = connector_status_disconnected; @@ -1139,7 +1140,7 @@ static int radeon_tv_get_modes(struct drm_connector *connector) struct drm_display_mode *tv_mode; struct drm_encoder *encoder; - encoder = radeon_best_single_encoder(connector); + encoder = radeon_best_single_encoder(connector, NULL); if (!encoder) return 0; @@ -1182,7 +1183,7 @@ radeon_tv_detect(struct drm_connector *connector, bool force) return connector_status_disconnected; } - encoder = radeon_best_single_encoder(connector); + encoder = radeon_best_single_encoder(connector, NULL); if (!encoder) ret = connector_status_disconnected; else { @@ -1439,7 +1440,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - encoder = connector_funcs->best_encoder(connector); + encoder = connector_funcs->best_encoder(connector, NULL); if (encoder && (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)) { radeon_connector_get_edid(connector); radeon_audio_detect(connector, encoder, ret); @@ -1456,7 +1457,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) } /* okay need to be smart in here about which encoder to pick */ -static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) +static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; struct radeon_connector *radeon_connector = to_radeon_connector(connector); @@ -1556,7 +1558,7 @@ static int radeon_dp_get_modes(struct drm_connector *connector) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; - struct drm_encoder *encoder = radeon_best_single_encoder(connector); + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); int ret; if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || @@ -1695,7 +1697,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) struct radeon_connector *radeon_connector = to_radeon_connector(connector); enum drm_connector_status ret = connector_status_disconnected; struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; - struct drm_encoder *encoder = radeon_best_single_encoder(connector); + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); int r; if (radeon_dig_connector->is_mst) @@ -1812,7 +1814,7 @@ static enum drm_mode_status radeon_dp_mode_valid(struct drm_connector *connector if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { - struct drm_encoder *encoder = radeon_best_single_encoder(connector); + struct drm_encoder *encoder = radeon_best_single_encoder(connector, NULL); if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) return MODE_PANEL; diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index cd8a3ee16649..fd5a0dae0e1f 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c @@ -224,7 +224,8 @@ radeon_dp_mst_mode_valid(struct drm_connector *connector, } static struct -drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector) +drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); @@ -613,7 +614,7 @@ radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector) struct radeon_encoder_mst *mst_enc; struct drm_encoder *encoder; const struct drm_connector_helper_funcs *connector_funcs = connector->base.helper_private; - struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base); + struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base, NULL); DRM_DEBUG_KMS("enc master is %p\n", enc_master); radeon_encoder = kzalloc(sizeof(*radeon_encoder), GFP_KERNEL); diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c index e7738939a86d..cdc991d5c28e 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c @@ -668,7 +668,8 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector) } static struct drm_encoder * -shmob_drm_connector_best_encoder(struct drm_connector *connector) +shmob_drm_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct shmob_drm_connector *scon = to_shmob_connector(connector); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index d616d64a6725..197962eca1af 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -178,8 +178,9 @@ static int panel_connector_mode_valid(struct drm_connector *connector, return tilcdc_crtc_mode_valid(priv->crtc, mode); } -static struct drm_encoder *panel_connector_best_encoder( - struct drm_connector *connector) +static struct drm_encoder * +panel_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct panel_connector *panel_connector = to_panel_connector(connector); return panel_connector->encoder; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c index c45cabb38db0..0ef8221c5334 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c @@ -191,8 +191,9 @@ static int tfp410_connector_mode_valid(struct drm_connector *connector, return tilcdc_crtc_mode_valid(priv->crtc, mode); } -static struct drm_encoder *tfp410_connector_best_encoder( - struct drm_connector *connector) +static struct drm_encoder * +tfp410_connector_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector); return tfp410_connector->encoder; diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index 09dc585aa46f..803ae6515892 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -145,7 +145,8 @@ udl_detect(struct drm_connector *connector, bool force) } static struct drm_encoder* -udl_best_single_encoder(struct drm_connector *connector) +udl_best_single_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; return drm_encoder_find(connector->dev, NULL, enc_id); diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index b265fe924556..bf0e93705e1c 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -370,8 +370,9 @@ static void vbox_encoder_destroy(struct drm_encoder *encoder) kfree(encoder); } -static struct drm_encoder *vbox_best_single_encoder(struct drm_connector - *connector) +static struct drm_encoder * +vbox_best_single_encoder(struct drm_connector *connector, + struct drm_crtc *crtc) { int enc_id = connector->encoder_ids[0]; diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 26aaba58d6ce..e0f00d43ed63 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -143,7 +143,8 @@ int drm_atomic_helper_page_flip_target( uint32_t target, struct drm_modeset_acquire_ctx *ctx); struct drm_encoder * -drm_atomic_helper_best_encoder(struct drm_connector *connector); +drm_atomic_helper_best_encoder(struct drm_connector *connector, + struct drm_crtc *crtc); /* default implementations for state handling */ void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 35e2a3a79fc5..a9b3a2c50877 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -885,7 +885,8 @@ struct drm_connector_helper_funcs { /** * @best_encoder: * - * This function should select the best encoder for the given connector. + * This function should select the best encoder for the given connector + * and crtc. For some driver internal use crtc may be NULL. * * This function is used by both the atomic helpers (in the * drm_atomic_helper_check_modeset() function) and in the legacy CRTC @@ -911,7 +912,8 @@ struct drm_connector_helper_funcs { * will ensure that encoders aren't used twice, drivers should not check * for this. */ - struct drm_encoder *(*best_encoder)(struct drm_connector *connector); + struct drm_encoder *(*best_encoder)(struct drm_connector *connector, + struct drm_crtc *crtc); /** * @atomic_best_encoder: