Commit fc10332b authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

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: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent a348c84d
...@@ -426,7 +426,11 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) ...@@ -426,7 +426,11 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
uint32_t adjusted_clock; uint32_t adjusted_clock;
uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
struct radeon_pll *pll; 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)); memset(&args, 0, sizeof(args));
...@@ -434,20 +438,20 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) ...@@ -434,20 +438,20 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
if ((rdev->family == CHIP_RS600) || if ((rdev->family == CHIP_RS600) ||
(rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS690) ||
(rdev->family == CHIP_RS740)) (rdev->family == CHIP_RS740))
pll_flags |= (RADEON_PLL_USE_FRAC_FB_DIV | pll->flags |= (RADEON_PLL_USE_FRAC_FB_DIV |
RADEON_PLL_PREFER_CLOSEST_LOWER); RADEON_PLL_PREFER_CLOSEST_LOWER);
if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ 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 else
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
} else { } else {
pll_flags |= RADEON_PLL_LEGACY; pll->flags |= RADEON_PLL_LEGACY;
if (mode->clock > 200000) /* range limits??? */ if (mode->clock > 200000) /* range limits??? */
pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
else 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) ...@@ -456,10 +460,10 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
if (!ASIC_IS_AVIVO(rdev)) { if (!ASIC_IS_AVIVO(rdev)) {
if (encoder->encoder_type != if (encoder->encoder_type !=
DRM_MODE_ENCODER_DAC) DRM_MODE_ENCODER_DAC)
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
if (encoder->encoder_type == if (encoder->encoder_type ==
DRM_MODE_ENCODER_LVDS) DRM_MODE_ENCODER_LVDS)
pll_flags |= RADEON_PLL_USE_REF_DIV; pll->flags |= RADEON_PLL_USE_REF_DIV;
} }
radeon_encoder = to_radeon_encoder(encoder); radeon_encoder = to_radeon_encoder(encoder);
break; break;
...@@ -494,23 +498,18 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) ...@@ -494,23 +498,18 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
adjusted_clock = mode->clock; 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 (ASIC_IS_AVIVO(rdev)) {
if (radeon_new_pll) if (radeon_new_pll)
radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock,
&fb_div, &frac_fb_div, &fb_div, &frac_fb_div,
&ref_div, &post_div, pll_flags); &ref_div, &post_div);
else else
radeon_compute_pll(pll, adjusted_clock, &pll_clock, radeon_compute_pll(pll, adjusted_clock, &pll_clock,
&fb_div, &frac_fb_div, &fb_div, &frac_fb_div,
&ref_div, &post_div, pll_flags); &ref_div, &post_div);
} else } else
radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, 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); index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
......
...@@ -411,11 +411,12 @@ void radeon_compute_pll(struct radeon_pll *pll, ...@@ -411,11 +411,12 @@ void radeon_compute_pll(struct radeon_pll *pll,
uint32_t *fb_div_p, uint32_t *fb_div_p,
uint32_t *frac_fb_div_p, uint32_t *frac_fb_div_p,
uint32_t *ref_div_p, uint32_t *ref_div_p,
uint32_t *post_div_p, uint32_t *post_div_p)
int flags)
{ {
uint32_t min_ref_div = pll->min_ref_div; uint32_t min_ref_div = pll->min_ref_div;
uint32_t max_ref_div = pll->max_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 min_fractional_feed_div = 0;
uint32_t max_fractional_feed_div = 0; uint32_t max_fractional_feed_div = 0;
uint32_t best_vco = pll->best_vco; uint32_t best_vco = pll->best_vco;
...@@ -431,7 +432,7 @@ void radeon_compute_pll(struct radeon_pll *pll, ...@@ -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); DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
freq = freq * 1000; 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; min_ref_div = max_ref_div = pll->reference_div;
else { else {
while (min_ref_div < max_ref_div-1) { while (min_ref_div < max_ref_div-1) {
...@@ -446,19 +447,22 @@ void radeon_compute_pll(struct radeon_pll *pll, ...@@ -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; min_fractional_feed_div = pll->min_frac_feedback_div;
max_fractional_feed_div = pll->max_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; 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; continue;
/* legacy radeons only have a few post_divs */ /* legacy radeons only have a few post_divs */
if (flags & RADEON_PLL_LEGACY) { if (pll->flags & RADEON_PLL_LEGACY) {
if ((post_div == 5) || if ((post_div == 5) ||
(post_div == 7) || (post_div == 7) ||
(post_div == 9) || (post_div == 9) ||
...@@ -505,7 +509,7 @@ void radeon_compute_pll(struct radeon_pll *pll, ...@@ -505,7 +509,7 @@ void radeon_compute_pll(struct radeon_pll *pll,
tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div; tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div;
current_freq = radeon_div(tmp, ref_div * post_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 = freq - current_freq;
error = error < 0 ? 0xffffffff : error; error = error < 0 ? 0xffffffff : error;
} else } else
...@@ -532,12 +536,12 @@ void radeon_compute_pll(struct radeon_pll *pll, ...@@ -532,12 +536,12 @@ void radeon_compute_pll(struct radeon_pll *pll,
best_freq = current_freq; best_freq = current_freq;
best_error = error; best_error = error;
best_vco_diff = vco_diff; best_vco_diff = vco_diff;
} else if (((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) || } else if (((pll->flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
((flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) || ((pll->flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
((flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) || ((pll->flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
((flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) || ((pll->flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
((flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) || ((pll->flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
((flags & RADEON_PLL_PREFER_HIGH_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_post_div = post_div;
best_ref_div = ref_div; best_ref_div = ref_div;
best_feedback_div = feedback_div; best_feedback_div = feedback_div;
...@@ -573,8 +577,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, ...@@ -573,8 +577,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
uint32_t *fb_div_p, uint32_t *fb_div_p,
uint32_t *frac_fb_div_p, uint32_t *frac_fb_div_p,
uint32_t *ref_div_p, uint32_t *ref_div_p,
uint32_t *post_div_p, uint32_t *post_div_p)
int flags)
{ {
fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq; fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq;
fixed20_12 pll_out_max, pll_out_min; 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) ...@@ -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 post_divider = 0;
uint32_t freq = 0; uint32_t freq = 0;
uint8_t pll_gain; uint8_t pll_gain;
int pll_flags = RADEON_PLL_LEGACY;
bool use_bios_divs = false; bool use_bios_divs = false;
/* PLL registers */ /* PLL registers */
uint32_t pll_ref_div = 0; uint32_t pll_ref_div = 0;
...@@ -726,10 +725,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) ...@@ -726,10 +725,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
else else
pll = &rdev->clock.p1pll; pll = &rdev->clock.p1pll;
pll->flags = RADEON_PLL_LEGACY;
if (mode->clock > 200000) /* range limits??? */ if (mode->clock > 200000) /* range limits??? */
pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
else 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) { list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->crtc == crtc) { if (encoder->crtc == crtc) {
...@@ -741,7 +742,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) ...@@ -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) 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 (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
if (!rdev->is_atom_bios) { if (!rdev->is_atom_bios) {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 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) ...@@ -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) ...@@ -766,8 +767,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
if (!use_bios_divs) { if (!use_bios_divs) {
radeon_compute_pll(pll, mode->clock, radeon_compute_pll(pll, mode->clock,
&freq, &feedback_div, &frac_fb_div, &freq, &feedback_div, &frac_fb_div,
&reference_div, &post_divider, &reference_div, &post_divider);
pll_flags);
for (post_div = &post_divs[0]; post_div->divider; ++post_div) { for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
if (post_div->divider == post_divider) if (post_div->divider == post_divider)
......
...@@ -125,16 +125,24 @@ struct radeon_tmds_pll { ...@@ -125,16 +125,24 @@ struct radeon_tmds_pll {
#define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9) #define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9)
#define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10) #define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10)
#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
#define RADEON_PLL_USE_POST_DIV (1 << 12)
struct radeon_pll { struct radeon_pll {
uint16_t reference_freq; /* reference frequency */
uint16_t reference_div; 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_min;
uint32_t pll_in_max; uint32_t pll_in_max;
uint32_t pll_out_min; uint32_t pll_out_min;
uint32_t pll_out_max; uint32_t pll_out_max;
uint16_t xclk; uint32_t best_vco;
/* divider limits */
uint32_t min_ref_div; uint32_t min_ref_div;
uint32_t max_ref_div; uint32_t max_ref_div;
uint32_t min_post_div; uint32_t min_post_div;
...@@ -143,7 +151,12 @@ struct radeon_pll { ...@@ -143,7 +151,12 @@ struct radeon_pll {
uint32_t max_feedback_div; uint32_t max_feedback_div;
uint32_t min_frac_feedback_div; uint32_t min_frac_feedback_div;
uint32_t max_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 { struct radeon_i2c_chan {
...@@ -417,8 +430,7 @@ extern void radeon_compute_pll(struct radeon_pll *pll, ...@@ -417,8 +430,7 @@ extern void radeon_compute_pll(struct radeon_pll *pll,
uint32_t *fb_div_p, uint32_t *fb_div_p,
uint32_t *frac_fb_div_p, uint32_t *frac_fb_div_p,
uint32_t *ref_div_p, uint32_t *ref_div_p,
uint32_t *post_div_p, uint32_t *post_div_p);
int flags);
extern void radeon_compute_pll_avivo(struct radeon_pll *pll, extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
uint64_t freq, uint64_t freq,
...@@ -426,8 +438,7 @@ extern void radeon_compute_pll_avivo(struct radeon_pll *pll, ...@@ -426,8 +438,7 @@ extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
uint32_t *fb_div_p, uint32_t *fb_div_p,
uint32_t *frac_fb_div_p, uint32_t *frac_fb_div_p,
uint32_t *ref_div_p, uint32_t *ref_div_p,
uint32_t *post_div_p, uint32_t *post_div_p);
int flags);
extern void radeon_setup_encoder_clones(struct drm_device *dev); extern void radeon_setup_encoder_clones(struct drm_device *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment