drm/radeon/kms/avivo: fix some bugs in the display bandwidth setup

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@linux.ie>
This commit is contained in:
Alex Deucher 2009-12-09 14:40:06 -05:00 committed by Dave Airlie
parent 2e7b6f7fa6
commit 69b3b5e59b
3 changed files with 28 additions and 5 deletions

View File

@ -38,6 +38,23 @@ typedef union rfixed {
#define fixed_init_half(A) { .full = rfixed_const_half((A)) } #define fixed_init_half(A) { .full = rfixed_const_half((A)) }
#define rfixed_trunc(A) ((A).full >> 12) #define rfixed_trunc(A) ((A).full >> 12)
static inline u32 rfixed_floor(fixed20_12 A)
{
u32 non_frac = rfixed_trunc(A);
return rfixed_const(non_frac);
}
static inline u32 rfixed_ceil(fixed20_12 A)
{
u32 non_frac = rfixed_trunc(A);
if (A.full > rfixed_const(non_frac))
return rfixed_const(non_frac + 1);
else
return rfixed_const(non_frac);
}
static inline u32 rfixed_div(fixed20_12 A, fixed20_12 B) static inline u32 rfixed_div(fixed20_12 A, fixed20_12 B)
{ {
u64 tmp = ((u64)A.full << 13); u64 tmp = ((u64)A.full << 13);

View File

@ -260,8 +260,9 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev,
b.full = rfixed_const(mode->crtc_hdisplay); b.full = rfixed_const(mode->crtc_hdisplay);
c.full = rfixed_const(256); c.full = rfixed_const(256);
a.full = rfixed_mul(wm->num_line_pair, b); a.full = rfixed_div(b, c);
request_fifo_depth.full = rfixed_div(a, c); request_fifo_depth.full = rfixed_mul(a, wm->num_line_pair);
request_fifo_depth.full = rfixed_ceil(request_fifo_depth);
if (a.full < rfixed_const(4)) { if (a.full < rfixed_const(4)) {
wm->lb_request_fifo_depth = 4; wm->lb_request_fifo_depth = 4;
} else { } else {
@ -390,6 +391,7 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev,
a.full = rfixed_const(16); a.full = rfixed_const(16);
wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay); wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay);
wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a); wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a);
wm->priority_mark_max.full = rfixed_ceil(wm->priority_mark_max);
/* Determine estimated width */ /* Determine estimated width */
estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full;
@ -399,6 +401,7 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev,
} else { } else {
a.full = rfixed_const(16); a.full = rfixed_const(16);
wm->priority_mark.full = rfixed_div(estimated_width, a); wm->priority_mark.full = rfixed_div(estimated_width, a);
wm->priority_mark.full = rfixed_ceil(wm->priority_mark);
wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full;
} }
} }

View File

@ -889,8 +889,9 @@ void rv515_crtc_bandwidth_compute(struct radeon_device *rdev,
b.full = rfixed_const(mode->crtc_hdisplay); b.full = rfixed_const(mode->crtc_hdisplay);
c.full = rfixed_const(256); c.full = rfixed_const(256);
a.full = rfixed_mul(wm->num_line_pair, b); a.full = rfixed_div(b, c);
request_fifo_depth.full = rfixed_div(a, c); request_fifo_depth.full = rfixed_mul(a, wm->num_line_pair);
request_fifo_depth.full = rfixed_ceil(request_fifo_depth);
if (a.full < rfixed_const(4)) { if (a.full < rfixed_const(4)) {
wm->lb_request_fifo_depth = 4; wm->lb_request_fifo_depth = 4;
} else { } else {
@ -992,15 +993,17 @@ void rv515_crtc_bandwidth_compute(struct radeon_device *rdev,
a.full = rfixed_const(16); a.full = rfixed_const(16);
wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay); wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay);
wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a); wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a);
wm->priority_mark_max.full = rfixed_ceil(wm->priority_mark_max);
/* Determine estimated width */ /* Determine estimated width */
estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full;
estimated_width.full = rfixed_div(estimated_width, consumption_time); estimated_width.full = rfixed_div(estimated_width, consumption_time);
if (rfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { if (rfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) {
wm->priority_mark.full = rfixed_const(10); wm->priority_mark.full = wm->priority_mark_max.full;
} else { } else {
a.full = rfixed_const(16); a.full = rfixed_const(16);
wm->priority_mark.full = rfixed_div(estimated_width, a); wm->priority_mark.full = rfixed_div(estimated_width, a);
wm->priority_mark.full = rfixed_ceil(wm->priority_mark);
wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full;
} }
} }