summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c66
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h1
2 files changed, 39 insertions, 28 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 721f80e9568d..8e32c5891be1 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1492,16 +1492,16 @@ static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_crtc *test_crtc;
- struct radeon_crtc *radeon_test_crtc;
+ struct radeon_crtc *test_radeon_crtc;
u32 pll_in_use = 0;
list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
if (crtc == test_crtc)
continue;
- radeon_test_crtc = to_radeon_crtc(test_crtc);
- if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
- pll_in_use |= (1 << radeon_test_crtc->pll_id);
+ test_radeon_crtc = to_radeon_crtc(test_crtc);
+ if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
+ pll_in_use |= (1 << test_radeon_crtc->pll_id);
}
return pll_in_use;
}
@@ -1518,17 +1518,18 @@ static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- struct drm_encoder *test_encoder;
+ struct drm_crtc *test_crtc;
struct radeon_crtc *test_radeon_crtc;
- list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
- if (test_encoder->crtc && (test_encoder->crtc != crtc)) {
- if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
- /* for DP use the same PLL for all */
- test_radeon_crtc = to_radeon_crtc(test_encoder->crtc);
- if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
- return test_radeon_crtc->pll_id;
- }
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+ test_radeon_crtc = to_radeon_crtc(test_crtc);
+ if (test_radeon_crtc->encoder &&
+ ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
+ /* for DP use the same PLL for all */
+ if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
+ return test_radeon_crtc->pll_id;
}
}
return ATOM_PPLL_INVALID;
@@ -1547,10 +1548,8 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
- struct drm_encoder *test_encoder;
struct drm_crtc *test_crtc;
struct radeon_crtc *test_radeon_crtc;
- struct radeon_encoder *test_radeon_encoder;
u32 adjusted_clock, test_adjusted_clock;
adjusted_clock = radeon_crtc->adjusted_clock;
@@ -1558,20 +1557,25 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
if (adjusted_clock == 0)
return ATOM_PPLL_INVALID;
- list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
- if (test_encoder->crtc && (test_encoder->crtc != crtc)) {
- if (!ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
- test_radeon_encoder = to_radeon_encoder(test_encoder);
- test_crtc = test_encoder->crtc;
- test_radeon_crtc = to_radeon_crtc(test_crtc);
- /* for non-DP check the clock */
- test_adjusted_clock = test_radeon_crtc->adjusted_clock;
- if ((crtc->mode.clock == test_crtc->mode.clock) &&
- (adjusted_clock == test_adjusted_clock) &&
- (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) &&
- (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID))
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+ test_radeon_crtc = to_radeon_crtc(test_crtc);
+ if (test_radeon_crtc->encoder &&
+ !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
+ /* check if we are already driving this connector with another crtc */
+ if (test_radeon_crtc->connector == radeon_crtc->connector) {
+ /* if we are, return that pll */
+ if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
return test_radeon_crtc->pll_id;
}
+ /* for non-DP check the clock */
+ test_adjusted_clock = test_radeon_crtc->adjusted_clock;
+ if ((crtc->mode.clock == test_crtc->mode.clock) &&
+ (adjusted_clock == test_adjusted_clock) &&
+ (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) &&
+ (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID))
+ return test_radeon_crtc->pll_id;
}
}
return ATOM_PPLL_INVALID;
@@ -1793,11 +1797,15 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->crtc == crtc) {
radeon_crtc->encoder = encoder;
+ radeon_crtc->connector = radeon_get_connector_for_encoder(encoder);
break;
}
}
- if (radeon_crtc->encoder == NULL)
+ if ((radeon_crtc->encoder == NULL) || (radeon_crtc->connector == NULL)) {
+ radeon_crtc->encoder = NULL;
+ radeon_crtc->connector = NULL;
return false;
+ }
if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
return false;
if (!atombios_crtc_prepare_pll(crtc, adjusted_mode))
@@ -1874,6 +1882,7 @@ done:
radeon_crtc->pll_id = ATOM_PPLL_INVALID;
radeon_crtc->adjusted_clock = 0;
radeon_crtc->encoder = NULL;
+ radeon_crtc->connector = NULL;
}
static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
@@ -1925,5 +1934,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
radeon_crtc->pll_id = ATOM_PPLL_INVALID;
radeon_crtc->adjusted_clock = 0;
radeon_crtc->encoder = NULL;
+ radeon_crtc->connector = NULL;
drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
}
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 2d78645576d7..917d02750cf7 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -327,6 +327,7 @@ struct radeon_crtc {
u32 pll_post_div;
u32 pll_flags;
struct drm_encoder *encoder;
+ struct drm_connector *connector;
};
struct radeon_encoder_primary_dac {