29,6 → 29,7 |
#include "drmP.h" |
#include "rv515d.h" |
#include "radeon.h" |
#include "radeon_asic.h" |
#include "atom.h" |
#include "rv515_reg_safe.h" |
|
67,13 → 68,13 |
ISYNC_CPSCRATCH_IDLEGUI); |
radeon_ring_write(rdev, PACKET0(WAIT_UNTIL, 0)); |
radeon_ring_write(rdev, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); |
radeon_ring_write(rdev, PACKET0(0x170C, 0)); |
radeon_ring_write(rdev, 1 << 31); |
radeon_ring_write(rdev, PACKET0(R300_DST_PIPE_CONFIG, 0)); |
radeon_ring_write(rdev, R300_PIPE_AUTO_CONFIG); |
radeon_ring_write(rdev, PACKET0(GB_SELECT, 0)); |
radeon_ring_write(rdev, 0); |
radeon_ring_write(rdev, PACKET0(GB_ENABLE, 0)); |
radeon_ring_write(rdev, 0); |
radeon_ring_write(rdev, PACKET0(0x42C8, 0)); |
radeon_ring_write(rdev, PACKET0(R500_SU_REG_DEST, 0)); |
radeon_ring_write(rdev, (1 << rdev->num_gb_pipes) - 1); |
radeon_ring_write(rdev, PACKET0(VAP_INDEX_OFFSET, 0)); |
radeon_ring_write(rdev, 0); |
145,19 → 146,14 |
{ |
unsigned pipe_select_current, gb_pipe_select, tmp; |
|
r100_hdp_reset(rdev); |
r100_rb2d_reset(rdev); |
|
if (r100_gui_wait_for_idle(rdev)) { |
printk(KERN_WARNING "Failed to wait GUI idle while " |
"reseting GPU. Bad things might happen.\n"); |
} |
|
rv515_vga_render_disable(rdev); |
|
r420_pipes_init(rdev); |
gb_pipe_select = RREG32(0x402C); |
tmp = RREG32(0x170C); |
gb_pipe_select = RREG32(R400_GB_PIPE_SELECT); |
tmp = RREG32(R300_DST_PIPE_CONFIG); |
pipe_select_current = (tmp >> 2) & 3; |
tmp = (1 << pipe_select_current) | |
(((gb_pipe_select >> 8) & 0xF) << 4); |
172,91 → 168,6 |
} |
} |
|
int rv515_ga_reset(struct radeon_device *rdev) |
{ |
uint32_t tmp; |
bool reinit_cp; |
int i; |
|
reinit_cp = rdev->cp.ready; |
rdev->cp.ready = false; |
for (i = 0; i < rdev->usec_timeout; i++) { |
WREG32(CP_CSQ_MODE, 0); |
WREG32(CP_CSQ_CNTL, 0); |
WREG32(RBBM_SOFT_RESET, 0x32005); |
(void)RREG32(RBBM_SOFT_RESET); |
udelay(200); |
WREG32(RBBM_SOFT_RESET, 0); |
/* Wait to prevent race in RBBM_STATUS */ |
mdelay(1); |
tmp = RREG32(RBBM_STATUS); |
if (tmp & ((1 << 20) | (1 << 26))) { |
DRM_ERROR("VAP & CP still busy (RBBM_STATUS=0x%08X)\n", tmp); |
/* GA still busy soft reset it */ |
WREG32(0x429C, 0x200); |
WREG32(VAP_PVS_STATE_FLUSH_REG, 0); |
WREG32(0x43E0, 0); |
WREG32(0x43E4, 0); |
WREG32(0x24AC, 0); |
} |
/* Wait to prevent race in RBBM_STATUS */ |
mdelay(1); |
tmp = RREG32(RBBM_STATUS); |
if (!(tmp & ((1 << 20) | (1 << 26)))) { |
break; |
} |
} |
for (i = 0; i < rdev->usec_timeout; i++) { |
tmp = RREG32(RBBM_STATUS); |
if (!(tmp & ((1 << 20) | (1 << 26)))) { |
DRM_INFO("GA reset succeed (RBBM_STATUS=0x%08X)\n", |
tmp); |
DRM_INFO("GA_IDLE=0x%08X\n", RREG32(0x425C)); |
DRM_INFO("RB3D_RESET_STATUS=0x%08X\n", RREG32(0x46f0)); |
DRM_INFO("ISYNC_CNTL=0x%08X\n", RREG32(0x1724)); |
if (reinit_cp) { |
return r100_cp_init(rdev, rdev->cp.ring_size); |
} |
return 0; |
} |
DRM_UDELAY(1); |
} |
tmp = RREG32(RBBM_STATUS); |
DRM_ERROR("Failed to reset GA ! (RBBM_STATUS=0x%08X)\n", tmp); |
return -1; |
} |
|
int rv515_gpu_reset(struct radeon_device *rdev) |
{ |
uint32_t status; |
|
/* reset order likely matter */ |
status = RREG32(RBBM_STATUS); |
/* reset HDP */ |
r100_hdp_reset(rdev); |
/* reset rb2d */ |
if (status & ((1 << 17) | (1 << 18) | (1 << 27))) { |
r100_rb2d_reset(rdev); |
} |
/* reset GA */ |
if (status & ((1 << 20) | (1 << 26))) { |
rv515_ga_reset(rdev); |
} |
/* reset CP */ |
status = RREG32(RBBM_STATUS); |
if (status & (1 << 16)) { |
r100_cp_reset(rdev); |
} |
/* Check if GPU is idle */ |
status = RREG32(RBBM_STATUS); |
if (status & (1 << 31)) { |
DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status); |
return -1; |
} |
DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status); |
return 0; |
} |
|
static void rv515_vram_get_type(struct radeon_device *rdev) |
{ |
uint32_t tmp; |
279,19 → 190,14 |
|
void rv515_mc_init(struct radeon_device *rdev) |
{ |
fixed20_12 a; |
|
rv515_vram_get_type(rdev); |
r100_vram_init_sizes(rdev); |
radeon_vram_location(rdev, &rdev->mc, 0); |
rdev->mc.gtt_base_align = 0; |
if (!(rdev->flags & RADEON_IS_AGP)) |
radeon_gtt_location(rdev, &rdev->mc); |
/* FIXME: we should enforce default clock in case GPU is not in |
* default setup |
*/ |
a.full = rfixed_const(100); |
rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); |
rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); |
radeon_update_bandwidth_info(rdev); |
} |
|
uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg) |
339,7 → 245,7 |
|
tmp = RREG32(0x2140); |
seq_printf(m, "VAP_CNTL_STATUS 0x%08x\n", tmp); |
radeon_gpu_reset(rdev); |
radeon_asic_reset(rdev); |
tmp = RREG32(0x425C); |
seq_printf(m, "GA_IDLE 0x%08x\n", tmp); |
return 0; |
485,12 → 391,9 |
/* 1M ring buffer */ |
r = r100_cp_init(rdev, 1024 * 1024); |
if (r) { |
dev_err(rdev->dev, "failled initializing CP (%d).\n", r); |
dev_err(rdev->dev, "failed initializing CP (%d).\n", r); |
return r; |
} |
// r = r100_wb_init(rdev); |
// if (r) |
// dev_err(rdev->dev, "failled initializing WB (%d).\n", r); |
// r = r100_ib_init(rdev); |
// if (r) { |
// dev_err(rdev->dev, "failled initializing IB (%d).\n", r); |
515,6 → 418,8 |
/* Initialize surface registers */ |
radeon_surface_init(rdev); |
/* TODO: disable VGA need to use VGA request */ |
/* restore some register to sane defaults */ |
r100_restore_sanity(rdev); |
/* BIOS*/ |
if (!radeon_get_bios(rdev)) { |
if (ASIC_IS_AVIVO(rdev)) |
529,7 → 434,7 |
return -EINVAL; |
} |
/* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
if (radeon_gpu_reset(rdev)) { |
if (radeon_asic_reset(rdev)) { |
dev_warn(rdev->dev, |
"GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
RREG32(R_000E40_RBBM_STATUS), |
540,8 → 445,6 |
return -EINVAL; |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
/* Initialize power management */ |
radeon_pm_init(rdev); |
/* initialize AGP */ |
if (rdev->flags & RADEON_IS_AGP) { |
r = radeon_agp_init(rdev); |
840,20 → 743,20 |
return; |
} |
|
if (crtc->vsc.full > rfixed_const(2)) |
wm->num_line_pair.full = rfixed_const(2); |
if (crtc->vsc.full > dfixed_const(2)) |
wm->num_line_pair.full = dfixed_const(2); |
else |
wm->num_line_pair.full = rfixed_const(1); |
wm->num_line_pair.full = dfixed_const(1); |
|
b.full = rfixed_const(mode->crtc_hdisplay); |
c.full = rfixed_const(256); |
a.full = rfixed_div(b, 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)) { |
b.full = dfixed_const(mode->crtc_hdisplay); |
c.full = dfixed_const(256); |
a.full = dfixed_div(b, c); |
request_fifo_depth.full = dfixed_mul(a, wm->num_line_pair); |
request_fifo_depth.full = dfixed_ceil(request_fifo_depth); |
if (a.full < dfixed_const(4)) { |
wm->lb_request_fifo_depth = 4; |
} else { |
wm->lb_request_fifo_depth = rfixed_trunc(request_fifo_depth); |
wm->lb_request_fifo_depth = dfixed_trunc(request_fifo_depth); |
} |
|
/* Determine consumption rate |
862,23 → 765,23 |
* vsc = vertical scaling ratio, defined as source/destination |
* hsc = horizontal scaling ration, defined as source/destination |
*/ |
a.full = rfixed_const(mode->clock); |
b.full = rfixed_const(1000); |
a.full = rfixed_div(a, b); |
pclk.full = rfixed_div(b, a); |
a.full = dfixed_const(mode->clock); |
b.full = dfixed_const(1000); |
a.full = dfixed_div(a, b); |
pclk.full = dfixed_div(b, a); |
if (crtc->rmx_type != RMX_OFF) { |
b.full = rfixed_const(2); |
b.full = dfixed_const(2); |
if (crtc->vsc.full > b.full) |
b.full = crtc->vsc.full; |
b.full = rfixed_mul(b, crtc->hsc); |
c.full = rfixed_const(2); |
b.full = rfixed_div(b, c); |
consumption_time.full = rfixed_div(pclk, b); |
b.full = dfixed_mul(b, crtc->hsc); |
c.full = dfixed_const(2); |
b.full = dfixed_div(b, c); |
consumption_time.full = dfixed_div(pclk, b); |
} else { |
consumption_time.full = pclk.full; |
} |
a.full = rfixed_const(1); |
wm->consumption_rate.full = rfixed_div(a, consumption_time); |
a.full = dfixed_const(1); |
wm->consumption_rate.full = dfixed_div(a, consumption_time); |
|
|
/* Determine line time |
886,8 → 789,8 |
* LineTime = total number of horizontal pixels |
* pclk = pixel clock period(ns) |
*/ |
a.full = rfixed_const(crtc->base.mode.crtc_htotal); |
line_time.full = rfixed_mul(a, pclk); |
a.full = dfixed_const(crtc->base.mode.crtc_htotal); |
line_time.full = dfixed_mul(a, pclk); |
|
/* Determine active time |
* ActiveTime = time of active region of display within one line, |
894,10 → 797,10 |
* hactive = total number of horizontal active pixels |
* htotal = total number of horizontal pixels |
*/ |
a.full = rfixed_const(crtc->base.mode.crtc_htotal); |
b.full = rfixed_const(crtc->base.mode.crtc_hdisplay); |
wm->active_time.full = rfixed_mul(line_time, b); |
wm->active_time.full = rfixed_div(wm->active_time, a); |
a.full = dfixed_const(crtc->base.mode.crtc_htotal); |
b.full = dfixed_const(crtc->base.mode.crtc_hdisplay); |
wm->active_time.full = dfixed_mul(line_time, b); |
wm->active_time.full = dfixed_div(wm->active_time, a); |
|
/* Determine chunk time |
* ChunkTime = the time it takes the DCP to send one chunk of data |
904,9 → 807,9 |
* to the LB which consists of pipeline delay and inter chunk gap |
* sclk = system clock(Mhz) |
*/ |
a.full = rfixed_const(600 * 1000); |
chunk_time.full = rfixed_div(a, rdev->pm.sclk); |
read_delay_latency.full = rfixed_const(1000); |
a.full = dfixed_const(600 * 1000); |
chunk_time.full = dfixed_div(a, rdev->pm.sclk); |
read_delay_latency.full = dfixed_const(1000); |
|
/* Determine the worst case latency |
* NumLinePair = Number of line pairs to request(1=2 lines, 2=4 lines) |
916,9 → 819,9 |
* ChunkTime = time it takes the DCP to send one chunk of data to the LB |
* which consists of pipeline delay and inter chunk gap |
*/ |
if (rfixed_trunc(wm->num_line_pair) > 1) { |
a.full = rfixed_const(3); |
wm->worst_case_latency.full = rfixed_mul(a, chunk_time); |
if (dfixed_trunc(wm->num_line_pair) > 1) { |
a.full = dfixed_const(3); |
wm->worst_case_latency.full = dfixed_mul(a, chunk_time); |
wm->worst_case_latency.full += read_delay_latency.full; |
} else { |
wm->worst_case_latency.full = chunk_time.full + read_delay_latency.full; |
934,34 → 837,34 |
* of data to the LB which consists of |
* pipeline delay and inter chunk gap |
*/ |
if ((2+wm->lb_request_fifo_depth) >= rfixed_trunc(request_fifo_depth)) { |
if ((2+wm->lb_request_fifo_depth) >= dfixed_trunc(request_fifo_depth)) { |
tolerable_latency.full = line_time.full; |
} else { |
tolerable_latency.full = rfixed_const(wm->lb_request_fifo_depth - 2); |
tolerable_latency.full = dfixed_const(wm->lb_request_fifo_depth - 2); |
tolerable_latency.full = request_fifo_depth.full - tolerable_latency.full; |
tolerable_latency.full = rfixed_mul(tolerable_latency, chunk_time); |
tolerable_latency.full = dfixed_mul(tolerable_latency, chunk_time); |
tolerable_latency.full = line_time.full - tolerable_latency.full; |
} |
/* We assume worst case 32bits (4 bytes) */ |
wm->dbpp.full = rfixed_const(2 * 16); |
wm->dbpp.full = dfixed_const(2 * 16); |
|
/* Determine the maximum priority mark |
* width = viewport width in pixels |
*/ |
a.full = rfixed_const(16); |
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_ceil(wm->priority_mark_max); |
a.full = dfixed_const(16); |
wm->priority_mark_max.full = dfixed_const(crtc->base.mode.crtc_hdisplay); |
wm->priority_mark_max.full = dfixed_div(wm->priority_mark_max, a); |
wm->priority_mark_max.full = dfixed_ceil(wm->priority_mark_max); |
|
/* Determine estimated width */ |
estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; |
estimated_width.full = rfixed_div(estimated_width, consumption_time); |
if (rfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { |
estimated_width.full = dfixed_div(estimated_width, consumption_time); |
if (dfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { |
wm->priority_mark.full = wm->priority_mark_max.full; |
} else { |
a.full = rfixed_const(16); |
wm->priority_mark.full = rfixed_div(estimated_width, a); |
wm->priority_mark.full = rfixed_ceil(wm->priority_mark); |
a.full = dfixed_const(16); |
wm->priority_mark.full = dfixed_div(estimated_width, a); |
wm->priority_mark.full = dfixed_ceil(wm->priority_mark); |
wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; |
} |
} |
973,6 → 876,8 |
struct rv515_watermark wm0; |
struct rv515_watermark wm1; |
u32 tmp; |
u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF; |
u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF; |
fixed20_12 priority_mark02, priority_mark12, fill_rate; |
fixed20_12 a, b; |
|
990,121 → 895,126 |
WREG32(LB_MAX_REQ_OUTSTANDING, tmp); |
|
if (mode0 && mode1) { |
if (rfixed_trunc(wm0.dbpp) > 64) |
a.full = rfixed_div(wm0.dbpp, wm0.num_line_pair); |
if (dfixed_trunc(wm0.dbpp) > 64) |
a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); |
else |
a.full = wm0.num_line_pair.full; |
if (rfixed_trunc(wm1.dbpp) > 64) |
b.full = rfixed_div(wm1.dbpp, wm1.num_line_pair); |
if (dfixed_trunc(wm1.dbpp) > 64) |
b.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); |
else |
b.full = wm1.num_line_pair.full; |
a.full += b.full; |
fill_rate.full = rfixed_div(wm0.sclk, a); |
fill_rate.full = dfixed_div(wm0.sclk, a); |
if (wm0.consumption_rate.full > fill_rate.full) { |
b.full = wm0.consumption_rate.full - fill_rate.full; |
b.full = rfixed_mul(b, wm0.active_time); |
a.full = rfixed_const(16); |
b.full = rfixed_div(b, a); |
a.full = rfixed_mul(wm0.worst_case_latency, |
b.full = dfixed_mul(b, wm0.active_time); |
a.full = dfixed_const(16); |
b.full = dfixed_div(b, a); |
a.full = dfixed_mul(wm0.worst_case_latency, |
wm0.consumption_rate); |
priority_mark02.full = a.full + b.full; |
} else { |
a.full = rfixed_mul(wm0.worst_case_latency, |
a.full = dfixed_mul(wm0.worst_case_latency, |
wm0.consumption_rate); |
b.full = rfixed_const(16 * 1000); |
priority_mark02.full = rfixed_div(a, b); |
b.full = dfixed_const(16 * 1000); |
priority_mark02.full = dfixed_div(a, b); |
} |
if (wm1.consumption_rate.full > fill_rate.full) { |
b.full = wm1.consumption_rate.full - fill_rate.full; |
b.full = rfixed_mul(b, wm1.active_time); |
a.full = rfixed_const(16); |
b.full = rfixed_div(b, a); |
a.full = rfixed_mul(wm1.worst_case_latency, |
b.full = dfixed_mul(b, wm1.active_time); |
a.full = dfixed_const(16); |
b.full = dfixed_div(b, a); |
a.full = dfixed_mul(wm1.worst_case_latency, |
wm1.consumption_rate); |
priority_mark12.full = a.full + b.full; |
} else { |
a.full = rfixed_mul(wm1.worst_case_latency, |
a.full = dfixed_mul(wm1.worst_case_latency, |
wm1.consumption_rate); |
b.full = rfixed_const(16 * 1000); |
priority_mark12.full = rfixed_div(a, b); |
b.full = dfixed_const(16 * 1000); |
priority_mark12.full = dfixed_div(a, b); |
} |
if (wm0.priority_mark.full > priority_mark02.full) |
priority_mark02.full = wm0.priority_mark.full; |
if (rfixed_trunc(priority_mark02) < 0) |
if (dfixed_trunc(priority_mark02) < 0) |
priority_mark02.full = 0; |
if (wm0.priority_mark_max.full > priority_mark02.full) |
priority_mark02.full = wm0.priority_mark_max.full; |
if (wm1.priority_mark.full > priority_mark12.full) |
priority_mark12.full = wm1.priority_mark.full; |
if (rfixed_trunc(priority_mark12) < 0) |
if (dfixed_trunc(priority_mark12) < 0) |
priority_mark12.full = 0; |
if (wm1.priority_mark_max.full > priority_mark12.full) |
priority_mark12.full = wm1.priority_mark_max.full; |
WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02)); |
WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02)); |
WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12)); |
WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12)); |
d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); |
d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); |
if (rdev->disp_priority == 2) { |
d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; |
d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; |
} |
} else if (mode0) { |
if (rfixed_trunc(wm0.dbpp) > 64) |
a.full = rfixed_div(wm0.dbpp, wm0.num_line_pair); |
if (dfixed_trunc(wm0.dbpp) > 64) |
a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); |
else |
a.full = wm0.num_line_pair.full; |
fill_rate.full = rfixed_div(wm0.sclk, a); |
fill_rate.full = dfixed_div(wm0.sclk, a); |
if (wm0.consumption_rate.full > fill_rate.full) { |
b.full = wm0.consumption_rate.full - fill_rate.full; |
b.full = rfixed_mul(b, wm0.active_time); |
a.full = rfixed_const(16); |
b.full = rfixed_div(b, a); |
a.full = rfixed_mul(wm0.worst_case_latency, |
b.full = dfixed_mul(b, wm0.active_time); |
a.full = dfixed_const(16); |
b.full = dfixed_div(b, a); |
a.full = dfixed_mul(wm0.worst_case_latency, |
wm0.consumption_rate); |
priority_mark02.full = a.full + b.full; |
} else { |
a.full = rfixed_mul(wm0.worst_case_latency, |
a.full = dfixed_mul(wm0.worst_case_latency, |
wm0.consumption_rate); |
b.full = rfixed_const(16); |
priority_mark02.full = rfixed_div(a, b); |
b.full = dfixed_const(16); |
priority_mark02.full = dfixed_div(a, b); |
} |
if (wm0.priority_mark.full > priority_mark02.full) |
priority_mark02.full = wm0.priority_mark.full; |
if (rfixed_trunc(priority_mark02) < 0) |
if (dfixed_trunc(priority_mark02) < 0) |
priority_mark02.full = 0; |
if (wm0.priority_mark_max.full > priority_mark02.full) |
priority_mark02.full = wm0.priority_mark_max.full; |
WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02)); |
WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02)); |
WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); |
WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); |
} else { |
if (rfixed_trunc(wm1.dbpp) > 64) |
a.full = rfixed_div(wm1.dbpp, wm1.num_line_pair); |
d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); |
if (rdev->disp_priority == 2) |
d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; |
} else if (mode1) { |
if (dfixed_trunc(wm1.dbpp) > 64) |
a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); |
else |
a.full = wm1.num_line_pair.full; |
fill_rate.full = rfixed_div(wm1.sclk, a); |
fill_rate.full = dfixed_div(wm1.sclk, a); |
if (wm1.consumption_rate.full > fill_rate.full) { |
b.full = wm1.consumption_rate.full - fill_rate.full; |
b.full = rfixed_mul(b, wm1.active_time); |
a.full = rfixed_const(16); |
b.full = rfixed_div(b, a); |
a.full = rfixed_mul(wm1.worst_case_latency, |
b.full = dfixed_mul(b, wm1.active_time); |
a.full = dfixed_const(16); |
b.full = dfixed_div(b, a); |
a.full = dfixed_mul(wm1.worst_case_latency, |
wm1.consumption_rate); |
priority_mark12.full = a.full + b.full; |
} else { |
a.full = rfixed_mul(wm1.worst_case_latency, |
a.full = dfixed_mul(wm1.worst_case_latency, |
wm1.consumption_rate); |
b.full = rfixed_const(16 * 1000); |
priority_mark12.full = rfixed_div(a, b); |
b.full = dfixed_const(16 * 1000); |
priority_mark12.full = dfixed_div(a, b); |
} |
if (wm1.priority_mark.full > priority_mark12.full) |
priority_mark12.full = wm1.priority_mark.full; |
if (rfixed_trunc(priority_mark12) < 0) |
if (dfixed_trunc(priority_mark12) < 0) |
priority_mark12.full = 0; |
if (wm1.priority_mark_max.full > priority_mark12.full) |
priority_mark12.full = wm1.priority_mark_max.full; |
WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); |
WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); |
WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12)); |
WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12)); |
d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); |
if (rdev->disp_priority == 2) |
d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; |
} |
|
WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); |
WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); |
WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); |
WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); |
} |
|
void rv515_bandwidth_update(struct radeon_device *rdev) |
1113,6 → 1023,8 |
struct drm_display_mode *mode0 = NULL; |
struct drm_display_mode *mode1 = NULL; |
|
radeon_update_display_priority(rdev); |
|
if (rdev->mode_info.crtcs[0]->base.enabled) |
mode0 = &rdev->mode_info.crtcs[0]->base.mode; |
if (rdev->mode_info.crtcs[1]->base.enabled) |
1122,7 → 1034,8 |
* modes if the user specifies HIGH for displaypriority |
* option. |
*/ |
if (rdev->disp_priority == 2) { |
if ((rdev->disp_priority == 2) && |
(rdev->family == CHIP_RV515)) { |
tmp = RREG32_MC(MC_MISC_LAT_TIMER); |
tmp &= ~MC_DISP1R_INIT_LAT_MASK; |
tmp &= ~MC_DISP0R_INIT_LAT_MASK; |