summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drm_crtc.c5
-rw-r--r--linux-core/drm_crtc.h2
-rw-r--r--linux-core/drm_crtc_helper.c28
-rw-r--r--linux-core/drm_crtc_helper.h1
-rw-r--r--linux-core/intel_crt.c1
-rw-r--r--linux-core/intel_display.c11
-rw-r--r--linux-core/intel_drv.h4
-rw-r--r--linux-core/intel_dvo.c2
-rw-r--r--linux-core/intel_lvds.c2
-rw-r--r--linux-core/intel_sdvo.c2
-rw-r--r--linux-core/intel_tv.c2
11 files changed, 47 insertions, 13 deletions
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index 74e526bd..73c7f2a3 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -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;
}
}
diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h
index 6dbc88a4..390ab2d3 100644
--- a/linux-core/drm_crtc.h
+++ b/linux-core/drm_crtc.h
@@ -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);
diff --git a/linux-core/drm_crtc_helper.c b/linux-core/drm_crtc_helper.c
index f1a72707..a4168f68 100644
--- a/linux-core/drm_crtc_helper.c
+++ b/linux-core/drm_crtc_helper.c
@@ -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);
diff --git a/linux-core/drm_crtc_helper.h b/linux-core/drm_crtc_helper.h
index 80cb4b49..3a3a4d4f 100644
--- a/linux-core/drm_crtc_helper.h
+++ b/linux-core/drm_crtc_helper.h
@@ -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);
diff --git a/linux-core/intel_crt.c b/linux-core/intel_crt.c
index 21a1e7d7..bf7c449e 100644
--- a/linux-core/intel_crt.c
+++ b/linux-core/intel_crt.c
@@ -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)
diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c
index bbaa19d1..e23b3973 100644
--- a/linux-core/intel_display.c
+++ b/linux-core/intel_display.c
@@ -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;
+}
diff --git a/linux-core/intel_drv.h b/linux-core/intel_drv.h
index 0a5e350e..24287e37 100644
--- a/linux-core/intel_drv.h
+++ b/linux-core/intel_drv.h
@@ -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);
diff --git a/linux-core/intel_dvo.c b/linux-core/intel_dvo.c
index e895d5b6..b061b1c5 100644
--- a/linux-core/intel_dvo.c
+++ b/linux-core/intel_dvo.c
@@ -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.
diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c
index cbe8b53d..f2fe4612 100644
--- a/linux-core/intel_lvds.c
+++ b/linux-core/intel_lvds.c
@@ -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);
diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c
index d3ca2a20..9ae0d567 100644
--- a/linux-core/intel_sdvo.c
+++ b/linux-core/intel_sdvo.c
@@ -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. */
diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c
index c3b5c093..e45cfa3b 100644
--- a/linux-core/intel_tv.c
+++ b/linux-core/intel_tv.c
@@ -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));