mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-01-04 18:00:22 +01:00
drm/modesetting: add best encoder finding for modesetting
This asks the driver to suggest the best encoder for the connector during the pick crtcs stage. Need to also do this during mode setting stages
This commit is contained in:
parent
0dd000b578
commit
46c78a2223
11 changed files with 47 additions and 13 deletions
|
|
@ -2042,16 +2042,13 @@ out:
|
|||
}
|
||||
|
||||
int drm_mode_connector_attach_encoder(struct drm_connector *connector,
|
||||
struct drm_encoder *encoder)
|
||||
struct drm_encoder *encoder)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
|
||||
if (connector->encoder_ids[i] == 0) {
|
||||
connector->encoder_ids[i] = encoder->id;
|
||||
/* pick the first added encoder as the current */
|
||||
if (i == 0)
|
||||
connector->encoder = encoder;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -624,7 +624,7 @@ extern bool drm_create_tv_properties(struct drm_device *dev, int num_formats,
|
|||
extern char *drm_get_encoder_name(struct drm_encoder *encoder);
|
||||
|
||||
extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
|
||||
struct drm_encoder *encoder);
|
||||
struct drm_encoder *encoder);
|
||||
extern void drm_mode_connector_detach_encoder(struct drm_connector *connector,
|
||||
struct drm_encoder *encoder);
|
||||
|
||||
|
|
|
|||
|
|
@ -208,10 +208,17 @@ static void drm_pick_crtcs (struct drm_device *dev)
|
|||
struct drm_encoder *encoder, *encoder_equal;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_display_mode *des_mode = NULL, *modes, *modes_equal;
|
||||
struct drm_connector_helper_funcs *connector_funcs;
|
||||
int found;
|
||||
|
||||
/* clean out all the encoder/crtc combos */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
encoder->crtc = NULL;
|
||||
}
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
connector->encoder->crtc = NULL;
|
||||
connector_funcs = connector->helper_private;
|
||||
connector->encoder = NULL;
|
||||
|
||||
/* Don't hook up connectors that are disconnected ??
|
||||
*
|
||||
|
|
@ -249,7 +256,11 @@ static void drm_pick_crtcs (struct drm_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
encoder = connector->encoder;
|
||||
encoder = connector_funcs->best_encoder(connector);
|
||||
if (!encoder)
|
||||
continue;
|
||||
|
||||
connector->encoder = encoder;
|
||||
|
||||
c = -1;
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
|
|
@ -259,12 +270,12 @@ static void drm_pick_crtcs (struct drm_device *dev)
|
|||
if ((encoder->possible_crtcs & (1 << c)) == 0)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(connector_equal, &dev->mode_config.connector_list, head) {
|
||||
if (connector->id == connector_equal->id)
|
||||
list_for_each_entry(encoder_equal, &dev->mode_config.encoder_list, head) {
|
||||
if (encoder->id == encoder_equal->id)
|
||||
continue;
|
||||
|
||||
/* Find out if crtc has been assigned before */
|
||||
if (connector_equal->encoder->crtc == crtc)
|
||||
if (encoder_equal->crtc == crtc)
|
||||
assigned = 1;
|
||||
}
|
||||
|
||||
|
|
@ -281,6 +292,9 @@ static void drm_pick_crtcs (struct drm_device *dev)
|
|||
|
||||
encoder_equal = connector_equal->encoder;
|
||||
|
||||
if (!encoder_equal)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(modes, &connector->modes, head) {
|
||||
list_for_each_entry(modes_equal, &connector_equal->modes, head) {
|
||||
if (drm_mode_equal (modes, modes_equal)) {
|
||||
|
|
@ -301,8 +315,8 @@ clone:
|
|||
continue;
|
||||
|
||||
/* Found a CRTC to attach to, do it ! */
|
||||
connector->encoder->crtc = crtc;
|
||||
connector->encoder->crtc->desired_mode = des_mode;
|
||||
encoder->crtc = crtc;
|
||||
encoder->crtc->desired_mode = des_mode;
|
||||
connector->initial_x = 0;
|
||||
connector->initial_y = 0;
|
||||
DRM_DEBUG("Desired mode for CRTC %d is 0x%x:%s\n",c,des_mode->mode_id, des_mode->name);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ struct drm_connector_helper_funcs {
|
|||
int (*get_modes)(struct drm_connector *connector);
|
||||
int (*mode_valid)(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode);
|
||||
struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
|
||||
};
|
||||
|
||||
extern void drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
|
||||
|
|
|
|||
|
|
@ -245,6 +245,7 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = {
|
|||
static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = {
|
||||
.mode_valid = intel_crt_mode_valid,
|
||||
.get_modes = intel_crt_get_modes,
|
||||
.best_encoder = intel_best_encoder,
|
||||
};
|
||||
|
||||
void intel_crt_enc_destroy(struct drm_encoder *encoder)
|
||||
|
|
|
|||
|
|
@ -1489,3 +1489,14 @@ void intel_modeset_cleanup(struct drm_device *dev)
|
|||
{
|
||||
drm_mode_config_cleanup(dev);
|
||||
}
|
||||
|
||||
|
||||
/* current intel driver doesn't take advantage of encoders
|
||||
always give back the encoder for the connector
|
||||
*/
|
||||
struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
|
||||
{
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
|
||||
return &intel_output->enc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ extern void intel_lvds_init(struct drm_device *dev);
|
|||
extern void intel_crtc_load_lut(struct drm_crtc *crtc);
|
||||
extern void intel_encoder_prepare (struct drm_encoder *encoder);
|
||||
extern void intel_encoder_commit (struct drm_encoder *encoder);
|
||||
|
||||
extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
|
||||
|
||||
extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
|
||||
struct drm_crtc *crtc);
|
||||
extern void intel_wait_for_vblank(struct drm_device *dev);
|
||||
|
|
@ -98,7 +101,6 @@ extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
|
|||
extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
|
||||
extern int intel_sdvo_supports_hotplug(struct drm_connector *connector);
|
||||
extern void intel_sdvo_set_hotplug(struct drm_connector *connector, int enable);
|
||||
|
||||
extern int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_connector *connector);
|
||||
extern int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
|
||||
extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc);
|
||||
|
|
|
|||
|
|
@ -342,6 +342,7 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = {
|
|||
static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
|
||||
.mode_valid = intel_dvo_mode_valid,
|
||||
.get_modes = intel_dvo_get_modes,
|
||||
.best_encoder = intel_best_encoder,
|
||||
};
|
||||
|
||||
void intel_dvo_enc_destroy(struct drm_encoder *encoder)
|
||||
|
|
@ -479,6 +480,7 @@ void intel_dvo_init(struct drm_device *dev)
|
|||
drm_encoder_init(dev, &intel_output->enc, &intel_dvo_enc_funcs, encoder_type);
|
||||
drm_encoder_helper_add(&intel_output->enc, &intel_dvo_helper_funcs);
|
||||
|
||||
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
|
||||
if (dvo->type == INTEL_DVO_CHIP_LVDS) {
|
||||
/* For our LVDS chipsets, we should hopefully be able
|
||||
* to dig the fixed panel mode out of the BIOS data.
|
||||
|
|
|
|||
|
|
@ -345,6 +345,7 @@ static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
|
|||
static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
|
||||
.get_modes = intel_lvds_get_modes,
|
||||
.mode_valid = intel_lvds_mode_valid,
|
||||
.best_encoder = intel_best_encoder,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs intel_lvds_connector_funcs = {
|
||||
|
|
@ -398,6 +399,7 @@ void intel_lvds_init(struct drm_device *dev)
|
|||
drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
|
||||
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
|
||||
intel_output->type = INTEL_OUTPUT_LVDS;
|
||||
|
||||
drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
|
||||
|
|
|
|||
|
|
@ -990,6 +990,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
|
|||
static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
|
||||
.get_modes = intel_sdvo_get_modes,
|
||||
.mode_valid = intel_sdvo_mode_valid,
|
||||
.best_encoder = intel_best_encoder,
|
||||
};
|
||||
|
||||
void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
|
||||
|
|
@ -1114,6 +1115,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device)
|
|||
drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
|
||||
connector->connector_type = connector_type;
|
||||
|
||||
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
|
||||
drm_sysfs_connector_add(connector);
|
||||
|
||||
/* Set the input timing to the screen. Assume always input 0. */
|
||||
|
|
|
|||
|
|
@ -1617,6 +1617,7 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = {
|
|||
static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
|
||||
.mode_valid = intel_tv_mode_valid,
|
||||
.get_modes = intel_tv_get_modes,
|
||||
.best_encoder = intel_best_encoder,
|
||||
};
|
||||
|
||||
void intel_tv_enc_destroy(struct drm_encoder *encoder)
|
||||
|
|
@ -1683,6 +1684,7 @@ intel_tv_init(struct drm_device *dev)
|
|||
drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs,
|
||||
DRM_MODE_ENCODER_TVDAC);
|
||||
|
||||
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
|
||||
tv_priv = (struct intel_tv_priv *)(intel_output + 1);
|
||||
intel_output->type = INTEL_OUTPUT_TVOUT;
|
||||
intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue