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:
Dave Airlie 2008-06-02 11:44:35 +10:00
parent 0dd000b578
commit 46c78a2223
11 changed files with 47 additions and 13 deletions

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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)

View file

@ -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;
}

View file

@ -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);

View file

@ -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.

View file

@ -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);

View file

@ -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. */

View file

@ -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));