drm/radeon/kms: clean up pll struct
- add a new flag for fixed post div - pull the pll flags into the struct Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
a348c84d95
commit
fc10332b8a
@ -426,7 +426,11 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
uint32_t adjusted_clock;
|
||||
uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
|
||||
struct radeon_pll *pll;
|
||||
int pll_flags = 0;
|
||||
|
||||
if (radeon_crtc->crtc_id == 0)
|
||||
pll = &rdev->clock.p1pll;
|
||||
else
|
||||
pll = &rdev->clock.p2pll;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
@ -434,20 +438,20 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
if ((rdev->family == CHIP_RS600) ||
|
||||
(rdev->family == CHIP_RS690) ||
|
||||
(rdev->family == CHIP_RS740))
|
||||
pll_flags |= (RADEON_PLL_USE_FRAC_FB_DIV |
|
||||
RADEON_PLL_PREFER_CLOSEST_LOWER);
|
||||
pll->flags |= (RADEON_PLL_USE_FRAC_FB_DIV |
|
||||
RADEON_PLL_PREFER_CLOSEST_LOWER);
|
||||
|
||||
if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */
|
||||
pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
|
||||
pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
|
||||
else
|
||||
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
} else {
|
||||
pll_flags |= RADEON_PLL_LEGACY;
|
||||
pll->flags |= RADEON_PLL_LEGACY;
|
||||
|
||||
if (mode->clock > 200000) /* range limits??? */
|
||||
pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
|
||||
pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
|
||||
else
|
||||
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
|
||||
}
|
||||
|
||||
@ -456,10 +460,10 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
if (!ASIC_IS_AVIVO(rdev)) {
|
||||
if (encoder->encoder_type !=
|
||||
DRM_MODE_ENCODER_DAC)
|
||||
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
||||
pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
||||
if (encoder->encoder_type ==
|
||||
DRM_MODE_ENCODER_LVDS)
|
||||
pll_flags |= RADEON_PLL_USE_REF_DIV;
|
||||
pll->flags |= RADEON_PLL_USE_REF_DIV;
|
||||
}
|
||||
radeon_encoder = to_radeon_encoder(encoder);
|
||||
break;
|
||||
@ -494,23 +498,18 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
adjusted_clock = mode->clock;
|
||||
}
|
||||
|
||||
if (radeon_crtc->crtc_id == 0)
|
||||
pll = &rdev->clock.p1pll;
|
||||
else
|
||||
pll = &rdev->clock.p2pll;
|
||||
|
||||
if (ASIC_IS_AVIVO(rdev)) {
|
||||
if (radeon_new_pll)
|
||||
radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock,
|
||||
&fb_div, &frac_fb_div,
|
||||
&ref_div, &post_div, pll_flags);
|
||||
&ref_div, &post_div);
|
||||
else
|
||||
radeon_compute_pll(pll, adjusted_clock, &pll_clock,
|
||||
&fb_div, &frac_fb_div,
|
||||
&ref_div, &post_div, pll_flags);
|
||||
&ref_div, &post_div);
|
||||
} else
|
||||
radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
|
||||
&ref_div, &post_div, pll_flags);
|
||||
&ref_div, &post_div);
|
||||
|
||||
index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
|
||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
|
||||
|
@ -411,11 +411,12 @@ void radeon_compute_pll(struct radeon_pll *pll,
|
||||
uint32_t *fb_div_p,
|
||||
uint32_t *frac_fb_div_p,
|
||||
uint32_t *ref_div_p,
|
||||
uint32_t *post_div_p,
|
||||
int flags)
|
||||
uint32_t *post_div_p)
|
||||
{
|
||||
uint32_t min_ref_div = pll->min_ref_div;
|
||||
uint32_t max_ref_div = pll->max_ref_div;
|
||||
uint32_t min_post_div = pll->min_post_div;
|
||||
uint32_t max_post_div = pll->max_post_div;
|
||||
uint32_t min_fractional_feed_div = 0;
|
||||
uint32_t max_fractional_feed_div = 0;
|
||||
uint32_t best_vco = pll->best_vco;
|
||||
@ -431,7 +432,7 @@ void radeon_compute_pll(struct radeon_pll *pll,
|
||||
DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
|
||||
freq = freq * 1000;
|
||||
|
||||
if (flags & RADEON_PLL_USE_REF_DIV)
|
||||
if (pll->flags & RADEON_PLL_USE_REF_DIV)
|
||||
min_ref_div = max_ref_div = pll->reference_div;
|
||||
else {
|
||||
while (min_ref_div < max_ref_div-1) {
|
||||
@ -446,19 +447,22 @@ void radeon_compute_pll(struct radeon_pll *pll,
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & RADEON_PLL_USE_FRAC_FB_DIV) {
|
||||
if (pll->flags & RADEON_PLL_USE_POST_DIV)
|
||||
min_post_div = max_post_div = pll->post_div;
|
||||
|
||||
if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
|
||||
min_fractional_feed_div = pll->min_frac_feedback_div;
|
||||
max_fractional_feed_div = pll->max_frac_feedback_div;
|
||||
}
|
||||
|
||||
for (post_div = pll->min_post_div; post_div <= pll->max_post_div; ++post_div) {
|
||||
for (post_div = min_post_div; post_div <= max_post_div; ++post_div) {
|
||||
uint32_t ref_div;
|
||||
|
||||
if ((flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
|
||||
if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
|
||||
continue;
|
||||
|
||||
/* legacy radeons only have a few post_divs */
|
||||
if (flags & RADEON_PLL_LEGACY) {
|
||||
if (pll->flags & RADEON_PLL_LEGACY) {
|
||||
if ((post_div == 5) ||
|
||||
(post_div == 7) ||
|
||||
(post_div == 9) ||
|
||||
@ -505,7 +509,7 @@ void radeon_compute_pll(struct radeon_pll *pll,
|
||||
tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div;
|
||||
current_freq = radeon_div(tmp, ref_div * post_div);
|
||||
|
||||
if (flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
|
||||
if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
|
||||
error = freq - current_freq;
|
||||
error = error < 0 ? 0xffffffff : error;
|
||||
} else
|
||||
@ -532,12 +536,12 @@ void radeon_compute_pll(struct radeon_pll *pll,
|
||||
best_freq = current_freq;
|
||||
best_error = error;
|
||||
best_vco_diff = vco_diff;
|
||||
} else if (((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
|
||||
((flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
|
||||
((flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
|
||||
((flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
|
||||
((flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
|
||||
((flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) {
|
||||
} else if (((pll->flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
|
||||
((pll->flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
|
||||
((pll->flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
|
||||
((pll->flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
|
||||
((pll->flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
|
||||
((pll->flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) {
|
||||
best_post_div = post_div;
|
||||
best_ref_div = ref_div;
|
||||
best_feedback_div = feedback_div;
|
||||
@ -573,8 +577,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
|
||||
uint32_t *fb_div_p,
|
||||
uint32_t *frac_fb_div_p,
|
||||
uint32_t *ref_div_p,
|
||||
uint32_t *post_div_p,
|
||||
int flags)
|
||||
uint32_t *post_div_p)
|
||||
{
|
||||
fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq;
|
||||
fixed20_12 pll_out_max, pll_out_min;
|
||||
|
@ -692,7 +692,6 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
uint32_t post_divider = 0;
|
||||
uint32_t freq = 0;
|
||||
uint8_t pll_gain;
|
||||
int pll_flags = RADEON_PLL_LEGACY;
|
||||
bool use_bios_divs = false;
|
||||
/* PLL registers */
|
||||
uint32_t pll_ref_div = 0;
|
||||
@ -726,10 +725,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
else
|
||||
pll = &rdev->clock.p1pll;
|
||||
|
||||
pll->flags = RADEON_PLL_LEGACY;
|
||||
|
||||
if (mode->clock > 200000) /* range limits??? */
|
||||
pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
|
||||
pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
|
||||
else
|
||||
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (encoder->crtc == crtc) {
|
||||
@ -741,7 +742,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
}
|
||||
|
||||
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
|
||||
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
||||
pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
||||
if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
|
||||
if (!rdev->is_atom_bios) {
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
@ -756,7 +757,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
pll_flags |= RADEON_PLL_USE_REF_DIV;
|
||||
pll->flags |= RADEON_PLL_USE_REF_DIV;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -766,8 +767,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
if (!use_bios_divs) {
|
||||
radeon_compute_pll(pll, mode->clock,
|
||||
&freq, &feedback_div, &frac_fb_div,
|
||||
&reference_div, &post_divider,
|
||||
pll_flags);
|
||||
&reference_div, &post_divider);
|
||||
|
||||
for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
|
||||
if (post_div->divider == post_divider)
|
||||
|
@ -125,16 +125,24 @@ struct radeon_tmds_pll {
|
||||
#define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9)
|
||||
#define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10)
|
||||
#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
|
||||
#define RADEON_PLL_USE_POST_DIV (1 << 12)
|
||||
|
||||
struct radeon_pll {
|
||||
uint16_t reference_freq;
|
||||
uint16_t reference_div;
|
||||
/* reference frequency */
|
||||
uint32_t reference_freq;
|
||||
|
||||
/* fixed dividers */
|
||||
uint32_t reference_div;
|
||||
uint32_t post_div;
|
||||
|
||||
/* pll in/out limits */
|
||||
uint32_t pll_in_min;
|
||||
uint32_t pll_in_max;
|
||||
uint32_t pll_out_min;
|
||||
uint32_t pll_out_max;
|
||||
uint16_t xclk;
|
||||
uint32_t best_vco;
|
||||
|
||||
/* divider limits */
|
||||
uint32_t min_ref_div;
|
||||
uint32_t max_ref_div;
|
||||
uint32_t min_post_div;
|
||||
@ -143,7 +151,12 @@ struct radeon_pll {
|
||||
uint32_t max_feedback_div;
|
||||
uint32_t min_frac_feedback_div;
|
||||
uint32_t max_frac_feedback_div;
|
||||
uint32_t best_vco;
|
||||
|
||||
/* flags for the current clock */
|
||||
uint32_t flags;
|
||||
|
||||
/* pll id */
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
struct radeon_i2c_chan {
|
||||
@ -417,8 +430,7 @@ extern void radeon_compute_pll(struct radeon_pll *pll,
|
||||
uint32_t *fb_div_p,
|
||||
uint32_t *frac_fb_div_p,
|
||||
uint32_t *ref_div_p,
|
||||
uint32_t *post_div_p,
|
||||
int flags);
|
||||
uint32_t *post_div_p);
|
||||
|
||||
extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
|
||||
uint64_t freq,
|
||||
@ -426,8 +438,7 @@ extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
|
||||
uint32_t *fb_div_p,
|
||||
uint32_t *frac_fb_div_p,
|
||||
uint32_t *ref_div_p,
|
||||
uint32_t *post_div_p,
|
||||
int flags);
|
||||
uint32_t *post_div_p);
|
||||
|
||||
extern void radeon_setup_encoder_clones(struct drm_device *dev);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user