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:
committed by
Dave Airlie
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 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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) {
|
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 {
|
|||||||
#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 {
|
|||||||
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,
|
|||||||
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,
|
|||||||
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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user