Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 232817
b: refs/heads/master
c: f523f74
h: refs/heads/master
i:
  232815: 7ae5e50
v: v3
  • Loading branch information
Alex Deucher authored and Dave Airlie committed Feb 2, 2011
1 parent c165d0e commit 84bc9bd
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 51d4bf840a27fe02c883ddc6d9708af056773769
refs/heads/master: f523f74eac1897b13c05c88ce6e5de0a7c34578b
4 changes: 2 additions & 2 deletions trunk/drivers/gpu/drm/radeon/atombios_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,8 +951,8 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
/* adjust pixel clock as needed */
adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);

radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
&ref_div, &post_div);
radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
&ref_div, &post_div);

atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss);

Expand Down
123 changes: 116 additions & 7 deletions trunk/drivers/gpu/drm/radeon/radeon_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,115 @@ static int radeon_ddc_dump(struct drm_connector *connector)
return ret;
}

/* avivo */
static void avivo_get_fb_div(struct radeon_pll *pll,
u32 target_clock,
u32 post_div,
u32 ref_div,
u32 *fb_div,
u32 *frac_fb_div)
{
u32 tmp = post_div * ref_div;

tmp *= target_clock;
*fb_div = tmp / pll->reference_freq;
*frac_fb_div = tmp % pll->reference_freq;
}

static u32 avivo_get_post_div(struct radeon_pll *pll,
u32 target_clock)
{
u32 vco, post_div, tmp;

if (pll->flags & RADEON_PLL_USE_POST_DIV)
return pll->post_div;

if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP) {
if (pll->flags & RADEON_PLL_IS_LCD)
vco = pll->lcd_pll_out_min;
else
vco = pll->pll_out_min;
} else {
if (pll->flags & RADEON_PLL_IS_LCD)
vco = pll->lcd_pll_out_max;
else
vco = pll->pll_out_max;
}

post_div = vco / target_clock;
tmp = vco % target_clock;

if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP) {
if (tmp)
post_div++;
} else {
if (!tmp)
post_div--;
}

return post_div;
}

#define MAX_TOLERANCE 10

void radeon_compute_pll_avivo(struct radeon_pll *pll,
u32 freq,
u32 *dot_clock_p,
u32 *fb_div_p,
u32 *frac_fb_div_p,
u32 *ref_div_p,
u32 *post_div_p)
{
u32 target_clock = freq / 10;
u32 post_div = avivo_get_post_div(pll, target_clock);
u32 ref_div = pll->min_ref_div;
u32 fb_div = 0, frac_fb_div = 0, tmp;

if (pll->flags & RADEON_PLL_USE_REF_DIV)
ref_div = pll->reference_div;

if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
avivo_get_fb_div(pll, target_clock, post_div, ref_div, &fb_div, &frac_fb_div);
frac_fb_div = (100 * frac_fb_div) / pll->reference_freq;
if (frac_fb_div >= 5) {
frac_fb_div -= 5;
frac_fb_div = frac_fb_div / 10;
frac_fb_div++;
}
if (frac_fb_div >= 10) {
fb_div++;
frac_fb_div = 0;
}
} else {
while (ref_div <= pll->max_ref_div) {
avivo_get_fb_div(pll, target_clock, post_div, ref_div,
&fb_div, &frac_fb_div);
if (frac_fb_div >= (pll->reference_freq / 2))
fb_div++;
frac_fb_div = 0;
tmp = (pll->reference_freq * fb_div) / (post_div * ref_div);
tmp = (tmp * 10000) / target_clock;

if (tmp > (10000 + MAX_TOLERANCE))
ref_div++;
else if (tmp >= (10000 - MAX_TOLERANCE))
break;
else
ref_div++;
}
}

*dot_clock_p = ((pll->reference_freq * fb_div * 10) + (pll->reference_freq * frac_fb_div)) /
(ref_div * post_div * 10);
*fb_div_p = fb_div;
*frac_fb_div_p = frac_fb_div;
*ref_div_p = ref_div;
*post_div_p = post_div;
DRM_DEBUG_KMS("%d, pll dividers - fb: %d.%d ref: %d, post %d\n",
*dot_clock_p, fb_div, frac_fb_div, ref_div, post_div);
}

/* pre-avivo */
static inline uint32_t radeon_div(uint64_t n, uint32_t d)
{
uint64_t mod;
Expand All @@ -790,13 +899,13 @@ static inline uint32_t radeon_div(uint64_t n, uint32_t d)
return n;
}

void radeon_compute_pll(struct radeon_pll *pll,
uint64_t freq,
uint32_t *dot_clock_p,
uint32_t *fb_div_p,
uint32_t *frac_fb_div_p,
uint32_t *ref_div_p,
uint32_t *post_div_p)
void radeon_compute_pll_legacy(struct radeon_pll *pll,
uint64_t freq,
uint32_t *dot_clock_p,
uint32_t *fb_div_p,
uint32_t *frac_fb_div_p,
uint32_t *ref_div_p,
uint32_t *post_div_p)
{
uint32_t min_ref_div = pll->min_ref_div;
uint32_t max_ref_div = pll->max_ref_div;
Expand Down
6 changes: 3 additions & 3 deletions trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,9 +778,9 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
DRM_DEBUG_KMS("\n");

if (!use_bios_divs) {
radeon_compute_pll(pll, mode->clock,
&freq, &feedback_div, &frac_fb_div,
&reference_div, &post_divider);
radeon_compute_pll_legacy(pll, mode->clock,
&freq, &feedback_div, &frac_fb_div,
&reference_div, &post_divider);

for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
if (post_div->divider == post_divider)
Expand Down
23 changes: 16 additions & 7 deletions trunk/drivers/gpu/drm/radeon/radeon_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ struct radeon_tmds_pll {
#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
#define RADEON_PLL_USE_POST_DIV (1 << 12)
#define RADEON_PLL_IS_LCD (1 << 13)
#define RADEON_PLL_PREFER_MINM_OVER_MAXP (1 << 14)

struct radeon_pll {
/* reference frequency */
Expand Down Expand Up @@ -510,13 +511,21 @@ extern bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
struct radeon_atom_ss *ss,
int id, u32 clock);

extern void radeon_compute_pll(struct radeon_pll *pll,
uint64_t freq,
uint32_t *dot_clock_p,
uint32_t *fb_div_p,
uint32_t *frac_fb_div_p,
uint32_t *ref_div_p,
uint32_t *post_div_p);
extern void radeon_compute_pll_legacy(struct radeon_pll *pll,
uint64_t freq,
uint32_t *dot_clock_p,
uint32_t *fb_div_p,
uint32_t *frac_fb_div_p,
uint32_t *ref_div_p,
uint32_t *post_div_p);

extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
u32 freq,
u32 *dot_clock_p,
u32 *fb_div_p,
u32 *frac_fb_div_p,
u32 *ref_div_p,
u32 *post_div_p);

extern void radeon_setup_encoder_clones(struct drm_device *dev);

Expand Down

0 comments on commit 84bc9bd

Please sign in to comment.